possumwood
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
exprtk.hpp
Go to the documentation of this file.
1 /*
2  ******************************************************************
3  * C++ Mathematical Expression Toolkit Library *
4  * *
5  * Author: Arash Partow (1999-2018) *
6  * URL: http://www.partow.net/programming/exprtk/index.html *
7  * *
8  * Copyright notice: *
9  * Free use of the C++ Mathematical Expression Toolkit Library is *
10  * permitted under the guidelines and in accordance with the most *
11  * current version of the MIT License. *
12  * http://www.opensource.org/licenses/MIT *
13  * *
14  * Example expressions: *
15  * (00) (y + x / y) * (x - y / x) *
16  * (01) (x^2 / sin(2 * pi / y)) - x / 2 *
17  * (02) sqrt(1 - (x^2)) *
18  * (03) 1 - sin(2 * x) + cos(pi / y) *
19  * (04) a * exp(2 * t) + c *
20  * (05) if(((x + 2) == 3) and ((y + 5) <= 9),1 + w, 2 / z) *
21  * (06) (avg(x,y) <= x + y ? x - y : x * y) + 2 * pi / x *
22  * (07) z := x + sin(2 * pi / y) *
23  * (08) u := 2 * (pi * z) / (w := x + cos(y / pi)) *
24  * (09) clamp(-1,sin(2 * pi * x) + cos(y / 2 * pi),+1) *
25  * (10) inrange(-2,m,+2) == if(({-2 <= m} and [m <= +2]),1,0) *
26  * (11) (2sin(x)cos(2y)7 + 1) == (2 * sin(x) * cos(2*y) * 7 + 1) *
27  * (12) (x ilike 's*ri?g') and [y < (3 z^7 + w)] *
28  * *
29  ******************************************************************
30 */
31 
32 
33 #ifndef INCLUDE_EXPRTK_HPP
34 #define INCLUDE_EXPRTK_HPP
35 
36 
37 #include <algorithm>
38 #include <cctype>
39 #include <cmath>
40 #include <complex>
41 #include <cstdio>
42 #include <cstdlib>
43 #include <cstring>
44 #include <deque>
45 #include <exception>
46 #include <functional>
47 #include <iterator>
48 #include <limits>
49 #include <list>
50 #include <map>
51 #include <set>
52 #include <stack>
53 #include <stdexcept>
54 #include <string>
55 #include <utility>
56 #include <vector>
57 
58 
59 namespace exprtk
60 {
61  #ifdef exprtk_enable_debugging
62  #define exprtk_debug(params) printf params
63  #else
64  #define exprtk_debug(params) (void)0
65  #endif
66 
67  #define exprtk_error_location \
68  "exprtk.hpp:" + details::to_str(__LINE__) \
69 
70  #if defined(__GNUC__) && (__GNUC__ >= 7)
71 
72  #define exprtk_disable_fallthrough_begin \
73  _Pragma ("GCC diagnostic push") \
74  _Pragma ("GCC diagnostic ignored \"-Wimplicit-fallthrough\"") \
75 
76  #define exprtk_disable_fallthrough_end \
77  _Pragma ("GCC diagnostic pop") \
78 
79  #else
80  #define exprtk_disable_fallthrough_begin (void)0;
81  #define exprtk_disable_fallthrough_end (void)0;
82  #endif
83 
84  namespace details
85  {
86  typedef unsigned char uchar_t;
87  typedef char char_t;
88  typedef uchar_t* uchar_ptr;
89  typedef char_t* char_ptr;
90  typedef uchar_t const* uchar_cptr;
91  typedef char_t const* char_cptr;
92 
93  inline bool is_whitespace(const char_t c)
94  {
95  return (' ' == c) || ('\n' == c) ||
96  ('\r' == c) || ('\t' == c) ||
97  ('\b' == c) || ('\v' == c) ||
98  ('\f' == c) ;
99  }
100 
101  inline bool is_operator_char(const char_t c)
102  {
103  return ('+' == c) || ('-' == c) ||
104  ('*' == c) || ('/' == c) ||
105  ('^' == c) || ('<' == c) ||
106  ('>' == c) || ('=' == c) ||
107  (',' == c) || ('!' == c) ||
108  ('(' == c) || (')' == c) ||
109  ('[' == c) || (']' == c) ||
110  ('{' == c) || ('}' == c) ||
111  ('%' == c) || (':' == c) ||
112  ('?' == c) || ('&' == c) ||
113  ('|' == c) || (';' == c) ;
114  }
115 
116  inline bool is_letter(const char_t c)
117  {
118  return (('a' <= c) && (c <= 'z')) ||
119  (('A' <= c) && (c <= 'Z')) ;
120  }
121 
122  inline bool is_digit(const char_t c)
123  {
124  return ('0' <= c) && (c <= '9');
125  }
126 
127  inline bool is_letter_or_digit(const char_t c)
128  {
129  return is_letter(c) || is_digit(c);
130  }
131 
132  inline bool is_left_bracket(const char_t c)
133  {
134  return ('(' == c) || ('[' == c) || ('{' == c);
135  }
136 
137  inline bool is_right_bracket(const char_t c)
138  {
139  return (')' == c) || (']' == c) || ('}' == c);
140  }
141 
142  inline bool is_bracket(const char_t c)
143  {
144  return is_left_bracket(c) || is_right_bracket(c);
145  }
146 
147  inline bool is_sign(const char_t c)
148  {
149  return ('+' == c) || ('-' == c);
150  }
151 
152  inline bool is_invalid(const char_t c)
153  {
154  return !is_whitespace (c) &&
155  !is_operator_char(c) &&
156  !is_letter (c) &&
157  !is_digit (c) &&
158  ('.' != c) &&
159  ('_' != c) &&
160  ('$' != c) &&
161  ('~' != c) &&
162  ('\'' != c);
163  }
164 
165  #ifndef exprtk_disable_caseinsensitivity
166  inline void case_normalise(std::string& s)
167  {
168  for (std::size_t i = 0; i < s.size(); ++i)
169  {
170  s[i] = static_cast<std::string::value_type>(std::tolower(s[i]));
171  }
172  }
173 
174  inline bool imatch(const char_t c1, const char_t c2)
175  {
176  return std::tolower(c1) == std::tolower(c2);
177  }
178 
179  inline bool imatch(const std::string& s1, const std::string& s2)
180  {
181  if (s1.size() == s2.size())
182  {
183  for (std::size_t i = 0; i < s1.size(); ++i)
184  {
185  if (std::tolower(s1[i]) != std::tolower(s2[i]))
186  {
187  return false;
188  }
189  }
190 
191  return true;
192  }
193 
194  return false;
195  }
196 
198  {
199  inline bool operator() (const std::string& s1, const std::string& s2) const
200  {
201  const std::size_t length = std::min(s1.size(),s2.size());
202 
203  for (std::size_t i = 0; i < length; ++i)
204  {
205  const char_t c1 = static_cast<char>(std::tolower(s1[i]));
206  const char_t c2 = static_cast<char>(std::tolower(s2[i]));
207 
208  if (c1 > c2)
209  return false;
210  else if (c1 < c2)
211  return true;
212  }
213 
214  return s1.size() < s2.size();
215  }
216  };
217 
218  #else
219  inline void case_normalise(std::string&)
220  {}
221 
222  inline bool imatch(const char_t c1, const char_t c2)
223  {
224  return c1 == c2;
225  }
226 
227  inline bool imatch(const std::string& s1, const std::string& s2)
228  {
229  return s1 == s2;
230  }
231 
232  struct ilesscompare
233  {
234  inline bool operator() (const std::string& s1, const std::string& s2) const
235  {
236  return s1 < s2;
237  }
238  };
239  #endif
240 
241  inline bool is_valid_sf_symbol(const std::string& symbol)
242  {
243  // Special function: $f12 or $F34
244  return (4 == symbol.size()) &&
245  ('$' == symbol[0]) &&
246  imatch('f',symbol[1]) &&
247  is_digit(symbol[2]) &&
248  is_digit(symbol[3]);
249  }
250 
251  inline const char_t& front(const std::string& s)
252  {
253  return s[0];
254  }
255 
256  inline const char_t& back(const std::string& s)
257  {
258  return s[s.size() - 1];
259  }
260 
261  inline std::string to_str(int i)
262  {
263  if (0 == i)
264  return std::string("0");
265 
266  std::string result;
267 
268  if (i < 0)
269  {
270  for ( ; i; i /= 10)
271  {
272  result += '0' + char(-(i % 10));
273  }
274 
275  result += '-';
276  }
277  else
278  {
279  for ( ; i; i /= 10)
280  {
281  result += '0' + char(i % 10);
282  }
283  }
284 
285  std::reverse(result.begin(), result.end());
286 
287  return result;
288  }
289 
290  inline std::string to_str(std::size_t i)
291  {
292  return to_str(static_cast<int>(i));
293  }
294 
295  inline bool is_hex_digit(const std::string::value_type digit)
296  {
297  return (('0' <= digit) && (digit <= '9')) ||
298  (('A' <= digit) && (digit <= 'F')) ||
299  (('a' <= digit) && (digit <= 'f')) ;
300  }
301 
303  {
304  if (('0' <= h) && (h <= '9'))
305  return (h - '0');
306  else
307  return static_cast<unsigned char>(std::toupper(h) - 'A');
308  }
309 
310  template <typename Iterator>
311  inline void parse_hex(Iterator& itr, Iterator end, std::string::value_type& result)
312  {
313  if (
314  (end != (itr )) &&
315  (end != (itr + 1)) &&
316  (end != (itr + 2)) &&
317  (end != (itr + 3)) &&
318  ('0' == *(itr )) &&
319  (
320  ('x' == *(itr + 1)) ||
321  ('X' == *(itr + 1))
322  ) &&
323  (is_hex_digit(*(itr + 2))) &&
324  (is_hex_digit(*(itr + 3)))
325  )
326  {
327  result = hex_to_bin(static_cast<uchar_t>(*(itr + 2))) << 4 |
328  hex_to_bin(static_cast<uchar_t>(*(itr + 3))) ;
329  itr += 3;
330  }
331  else
332  result = '\0';
333  }
334 
335  inline void cleanup_escapes(std::string& s)
336  {
337  typedef std::string::iterator str_itr_t;
338 
339  str_itr_t itr1 = s.begin();
340  str_itr_t itr2 = s.begin();
341  str_itr_t end = s.end ();
342 
343  std::size_t removal_count = 0;
344 
345  while (end != itr1)
346  {
347  if ('\\' == (*itr1))
348  {
349  ++removal_count;
350 
351  if (end == ++itr1)
352  break;
353  else if ('\\' != (*itr1))
354  {
355  switch (*itr1)
356  {
357  case 'n' : (*itr1) = '\n'; break;
358  case 'r' : (*itr1) = '\r'; break;
359  case 't' : (*itr1) = '\t'; break;
360  case '0' : parse_hex(itr1, end, (*itr1));
361  removal_count += 3;
362  break;
363  }
364 
365  continue;
366  }
367  }
368 
369  if (itr1 != itr2)
370  {
371  (*itr2) = (*itr1);
372  }
373 
374  ++itr1;
375  ++itr2;
376  }
377 
378  s.resize(s.size() - removal_count);
379  }
380 
382  {
383  public:
384 
385  build_string(const std::size_t& initial_size = 64)
386  {
387  data_.reserve(initial_size);
388  }
389 
390  inline build_string& operator << (const std::string& s)
391  {
392  data_ += s;
393  return (*this);
394  }
395 
397  {
398  data_ += std::string(s);
399  return (*this);
400  }
401 
402  inline operator std::string () const
403  {
404  return data_;
405  }
406 
407  inline std::string as_string() const
408  {
409  return data_;
410  }
411 
412  private:
413 
414  std::string data_;
415  };
416 
417  static const std::string reserved_words[] =
418  {
419  "break", "case", "continue", "default", "false", "for",
420  "if", "else", "ilike", "in", "like", "and", "nand", "nor",
421  "not", "null", "or", "repeat", "return", "shl", "shr",
422  "swap", "switch", "true", "until", "var", "while", "xnor",
423  "xor", "&", "|"
424  };
425 
426  static const std::size_t reserved_words_size = sizeof(reserved_words) / sizeof(std::string);
427 
428  static const std::string reserved_symbols[] =
429  {
430  "abs", "acos", "acosh", "and", "asin", "asinh", "atan",
431  "atanh", "atan2", "avg", "break", "case", "ceil", "clamp",
432  "continue", "cos", "cosh", "cot", "csc", "default",
433  "deg2grad", "deg2rad", "equal", "erf", "erfc", "exp",
434  "expm1", "false", "floor", "for", "frac", "grad2deg",
435  "hypot", "iclamp", "if", "else", "ilike", "in", "inrange",
436  "like", "log", "log10", "log2", "logn", "log1p", "mand",
437  "max", "min", "mod", "mor", "mul", "ncdf", "nand", "nor",
438  "not", "not_equal", "null", "or", "pow", "rad2deg",
439  "repeat", "return", "root", "round", "roundn", "sec", "sgn",
440  "shl", "shr", "sin", "sinc", "sinh", "sqrt", "sum", "swap",
441  "switch", "tan", "tanh", "true", "trunc", "until", "var",
442  "while", "xnor", "xor", "&", "|"
443  };
444 
445  static const std::size_t reserved_symbols_size = sizeof(reserved_symbols) / sizeof(std::string);
446 
447  static const std::string base_function_list[] =
448  {
449  "abs", "acos", "acosh", "asin", "asinh", "atan", "atanh",
450  "atan2", "avg", "ceil", "clamp", "cos", "cosh", "cot",
451  "csc", "equal", "erf", "erfc", "exp", "expm1", "floor",
452  "frac", "hypot", "iclamp", "like", "log", "log10", "log2",
453  "logn", "log1p", "mand", "max", "min", "mod", "mor", "mul",
454  "ncdf", "pow", "root", "round", "roundn", "sec", "sgn",
455  "sin", "sinc", "sinh", "sqrt", "sum", "swap", "tan", "tanh",
456  "trunc", "not_equal", "inrange", "deg2grad", "deg2rad",
457  "rad2deg", "grad2deg"
458  };
459 
460  static const std::size_t base_function_list_size = sizeof(base_function_list) / sizeof(std::string);
461 
462  static const std::string logic_ops_list[] =
463  {
464  "and", "nand", "nor", "not", "or", "xnor", "xor", "&", "|"
465  };
466 
467  static const std::size_t logic_ops_list_size = sizeof(logic_ops_list) / sizeof(std::string);
468 
469  static const std::string cntrl_struct_list[] =
470  {
471  "if", "switch", "for", "while", "repeat", "return"
472  };
473 
474  static const std::size_t cntrl_struct_list_size = sizeof(cntrl_struct_list) / sizeof(std::string);
475 
476  static const std::string arithmetic_ops_list[] =
477  {
478  "+", "-", "*", "/", "%", "^"
479  };
480 
481  static const std::size_t arithmetic_ops_list_size = sizeof(arithmetic_ops_list) / sizeof(std::string);
482 
483  static const std::string assignment_ops_list[] =
484  {
485  ":=", "+=", "-=",
486  "*=", "/=", "%="
487  };
488 
489  static const std::size_t assignment_ops_list_size = sizeof(assignment_ops_list) / sizeof(std::string);
490 
491  static const std::string inequality_ops_list[] =
492  {
493  "<", "<=", "==",
494  "=", "!=", "<>",
495  ">=", ">"
496  };
497 
498  static const std::size_t inequality_ops_list_size = sizeof(inequality_ops_list) / sizeof(std::string);
499 
500  inline bool is_reserved_word(const std::string& symbol)
501  {
502  for (std::size_t i = 0; i < reserved_words_size; ++i)
503  {
504  if (imatch(symbol, reserved_words[i]))
505  {
506  return true;
507  }
508  }
509 
510  return false;
511  }
512 
513  inline bool is_reserved_symbol(const std::string& symbol)
514  {
515  for (std::size_t i = 0; i < reserved_symbols_size; ++i)
516  {
517  if (imatch(symbol, reserved_symbols[i]))
518  {
519  return true;
520  }
521  }
522 
523  return false;
524  }
525 
526  inline bool is_base_function(const std::string& function_name)
527  {
528  for (std::size_t i = 0; i < base_function_list_size; ++i)
529  {
530  if (imatch(function_name, base_function_list[i]))
531  {
532  return true;
533  }
534  }
535 
536  return false;
537  }
538 
539  inline bool is_control_struct(const std::string& cntrl_strct)
540  {
541  for (std::size_t i = 0; i < cntrl_struct_list_size; ++i)
542  {
543  if (imatch(cntrl_strct, cntrl_struct_list[i]))
544  {
545  return true;
546  }
547  }
548 
549  return false;
550  }
551 
552  inline bool is_logic_opr(const std::string& lgc_opr)
553  {
554  for (std::size_t i = 0; i < logic_ops_list_size; ++i)
555  {
556  if (imatch(lgc_opr, logic_ops_list[i]))
557  {
558  return true;
559  }
560  }
561 
562  return false;
563  }
564 
565  struct cs_match
566  {
567  static inline bool cmp(const char_t c0, const char_t c1)
568  {
569  return (c0 == c1);
570  }
571  };
572 
573  struct cis_match
574  {
575  static inline bool cmp(const char_t c0, const char_t c1)
576  {
577  return (std::tolower(c0) == std::tolower(c1));
578  }
579  };
580 
581  template <typename Iterator, typename Compare>
582  inline bool match_impl(const Iterator pattern_begin,
583  const Iterator pattern_end,
584  const Iterator data_begin,
585  const Iterator data_end,
586  const typename std::iterator_traits<Iterator>::value_type& zero_or_more,
587  const typename std::iterator_traits<Iterator>::value_type& zero_or_one)
588  {
589  Iterator d_itr = data_begin;
590  Iterator p_itr = pattern_begin;
591 
592  while ((p_itr != pattern_end) && (d_itr != data_end))
593  {
594  if (zero_or_more == *p_itr)
595  {
596  while ((p_itr != pattern_end) && (*p_itr == zero_or_more || *p_itr == zero_or_one))
597  {
598  ++p_itr;
599  }
600 
601  if (p_itr == pattern_end)
602  return true;
603 
604  const typename std::iterator_traits<Iterator>::value_type c = *(p_itr++);
605 
606  while ((d_itr != data_end) && !Compare::cmp(c,*d_itr))
607  {
608  ++d_itr;
609  }
610 
611  ++d_itr;
612  }
613  else if ((*p_itr == zero_or_one) || Compare::cmp(*p_itr, *d_itr))
614  {
615  ++d_itr;
616  ++p_itr;
617  }
618  else
619  return false;
620  }
621 
622  if (d_itr != data_end)
623  return false;
624  else if (p_itr == pattern_end)
625  return true;
626  else if ((zero_or_more == *p_itr) || (zero_or_one == *p_itr))
627  ++p_itr;
628 
629  return pattern_end == p_itr;
630  }
631 
632  inline bool wc_match(const std::string& wild_card,
633  const std::string& str)
634  {
635  return match_impl<char_cptr,cs_match>(wild_card.data(),
636  wild_card.data() + wild_card.size(),
637  str.data(),
638  str.data() + str.size(),
639  '*',
640  '?');
641  }
642 
643  inline bool wc_imatch(const std::string& wild_card,
644  const std::string& str)
645  {
646  return match_impl<char_cptr,cis_match>(wild_card.data(),
647  wild_card.data() + wild_card.size(),
648  str.data(),
649  str.data() + str.size(),
650  '*',
651  '?');
652  }
653 
654  inline bool sequence_match(const std::string& pattern,
655  const std::string& str,
656  std::size_t& diff_index,
657  char_t& diff_value)
658  {
659  if (str.empty())
660  {
661  return ("Z" == pattern);
662  }
663  else if ('*' == pattern[0])
664  return false;
665 
666  typedef std::string::const_iterator itr_t;
667 
668  itr_t p_itr = pattern.begin();
669  itr_t s_itr = str .begin();
670 
671  itr_t p_end = pattern.end();
672  itr_t s_end = str .end();
673 
674  while ((s_end != s_itr) && (p_end != p_itr))
675  {
676  if ('*' == (*p_itr))
677  {
678  const char_t target = static_cast<char>(std::toupper(*(p_itr - 1)));
679 
680  if ('*' == target)
681  {
682  diff_index = static_cast<std::size_t>(std::distance(str.begin(),s_itr));
683  diff_value = static_cast<char>(std::toupper(*p_itr));
684 
685  return false;
686  }
687  else
688  ++p_itr;
689 
690  while (s_itr != s_end)
691  {
692  if (target != std::toupper(*s_itr))
693  break;
694  else
695  ++s_itr;
696  }
697 
698  continue;
699  }
700  else if (
701  ('?' != *p_itr) &&
702  std::toupper(*p_itr) != std::toupper(*s_itr)
703  )
704  {
705  diff_index = static_cast<std::size_t>(std::distance(str.begin(),s_itr));
706  diff_value = static_cast<char>(std::toupper(*p_itr));
707 
708  return false;
709  }
710 
711  ++p_itr;
712  ++s_itr;
713  }
714 
715  return (
716  (s_end == s_itr) &&
717  (
718  (p_end == p_itr) ||
719  ('*' == *p_itr)
720  )
721  );
722  }
723 
724  static const double pow10[] = {
725  1.0,
726  1.0E+001, 1.0E+002, 1.0E+003, 1.0E+004,
727  1.0E+005, 1.0E+006, 1.0E+007, 1.0E+008,
728  1.0E+009, 1.0E+010, 1.0E+011, 1.0E+012,
729  1.0E+013, 1.0E+014, 1.0E+015, 1.0E+016
730  };
731 
732  static const std::size_t pow10_size = sizeof(pow10) / sizeof(double);
733 
734  namespace numeric
735  {
736  namespace constant
737  {
738  static const double e = 2.71828182845904523536028747135266249775724709369996;
739  static const double pi = 3.14159265358979323846264338327950288419716939937510;
740  static const double pi_2 = 1.57079632679489661923132169163975144209858469968755;
741  static const double pi_4 = 0.78539816339744830961566084581987572104929234984378;
742  static const double pi_180 = 0.01745329251994329576923690768488612713442871888542;
743  static const double _1_pi = 0.31830988618379067153776752674502872406891929148091;
744  static const double _2_pi = 0.63661977236758134307553505349005744813783858296183;
745  static const double _180_pi = 57.29577951308232087679815481410517033240547246656443;
746  static const double log2 = 0.69314718055994530941723212145817656807550013436026;
747  static const double sqrt2 = 1.41421356237309504880168872420969807856967187537695;
748  }
749 
750  namespace details
751  {
753  struct real_type_tag { real_type_tag () {} };
755  struct int_type_tag { int_type_tag () {} };
756 
757  template <typename T>
758  struct number_type
759  {
762  };
763 
764  #define exprtk_register_real_type_tag(T) \
765  template<> struct number_type<T> \
766  { typedef real_type_tag type; number_type() {} }; \
767 
768  #define exprtk_register_complex_type_tag(T) \
769  template<> struct number_type<std::complex<T> > \
770  { typedef complex_type_tag type; number_type() {} }; \
771 
772  #define exprtk_register_int_type_tag(T) \
773  template<> struct number_type<T> \
774  { typedef int_type_tag type; number_type() {} }; \
775 
777  exprtk_register_real_type_tag(long double)
779 
783 
786  exprtk_register_int_type_tag(long long int )
787  exprtk_register_int_type_tag(unsigned short )
788  exprtk_register_int_type_tag(unsigned int )
789  exprtk_register_int_type_tag(unsigned long long int)
790 
791  #undef exprtk_register_real_type_tag
792  #undef exprtk_register_int_type_tag
793 
794  template <typename T>
795  struct epsilon_type
796  {
797  static inline T value()
798  {
799  const T epsilon = T(0.0000000001);
800  return epsilon;
801  }
802  };
803 
804  template <>
805  struct epsilon_type <float>
806  {
807  static inline float value()
808  {
809  const float epsilon = float(0.000001f);
810  return epsilon;
811  }
812  };
813 
814  template <>
815  struct epsilon_type <long double>
816  {
817  static inline long double value()
818  {
819  const long double epsilon = (long double)(0.000000000001);
820  return epsilon;
821  }
822  };
823 
824  template <typename T>
825  inline bool is_nan_impl(const T v, real_type_tag)
826  {
827  return std::not_equal_to<T>()(v,v);
828  }
829 
830  template <typename T>
831  inline int to_int32_impl(const T v, real_type_tag)
832  {
833  return static_cast<int>(v);
834  }
835 
836  template <typename T>
837  inline long long int to_int64_impl(const T v, real_type_tag)
838  {
839  return static_cast<long long int>(v);
840  }
841 
842  template <typename T>
843  inline bool is_true_impl(const T v)
844  {
845  return std::not_equal_to<T>()(T(0),v);
846  }
847 
848  template <typename T>
849  inline bool is_false_impl(const T v)
850  {
851  return std::equal_to<T>()(T(0),v);
852  }
853 
854  template <typename T>
855  inline T abs_impl(const T v, real_type_tag)
856  {
857  return ((v < T(0)) ? -v : v);
858  }
859 
860  template <typename T>
861  inline T min_impl(const T v0, const T v1, real_type_tag)
862  {
863  return std::min<T>(v0,v1);
864  }
865 
866  template <typename T>
867  inline T max_impl(const T v0, const T v1, real_type_tag)
868  {
869  return std::max<T>(v0,v1);
870  }
871 
872  template <typename T>
873  inline T equal_impl(const T v0, const T v1, real_type_tag)
874  {
875  const T epsilon = epsilon_type<T>::value();
876  return (abs_impl(v0 - v1,real_type_tag()) <= (std::max(T(1),std::max(abs_impl(v0,real_type_tag()),abs_impl(v1,real_type_tag()))) * epsilon)) ? T(1) : T(0);
877  }
878 
879  inline float equal_impl(const float v0, const float v1, real_type_tag)
880  {
881  const float epsilon = epsilon_type<float>::value();
882  return (abs_impl(v0 - v1,real_type_tag()) <= (std::max(1.0f,std::max(abs_impl(v0,real_type_tag()),abs_impl(v1,real_type_tag()))) * epsilon)) ? 1.0f : 0.0f;
883  }
884 
885  template <typename T>
886  inline T equal_impl(const T v0, const T v1, int_type_tag)
887  {
888  return (v0 == v1) ? 1 : 0;
889  }
890 
891  template <typename T>
892  inline T expm1_impl(const T v, real_type_tag)
893  {
894  // return std::expm1<T>(v);
895  if (abs_impl(v,real_type_tag()) < T(0.00001))
896  return v + (T(0.5) * v * v);
897  else
898  return std::exp(v) - T(1);
899  }
900 
901  template <typename T>
902  inline T expm1_impl(const T v, int_type_tag)
903  {
904  return T(std::exp<double>(v)) - T(1);
905  }
906 
907  template <typename T>
908  inline T nequal_impl(const T v0, const T v1, real_type_tag)
909  {
910  typedef real_type_tag rtg;
911  const T epsilon = epsilon_type<T>::value();
912  return (abs_impl(v0 - v1,rtg()) > (std::max(T(1),std::max(abs_impl(v0,rtg()),abs_impl(v1,rtg()))) * epsilon)) ? T(1) : T(0);
913  }
914 
915  inline float nequal_impl(const float v0, const float v1, real_type_tag)
916  {
917  typedef real_type_tag rtg;
918  const float epsilon = epsilon_type<float>::value();
919  return (abs_impl(v0 - v1,rtg()) > (std::max(1.0f,std::max(abs_impl(v0,rtg()),abs_impl(v1,rtg()))) * epsilon)) ? 1.0f : 0.0f;
920  }
921 
922  template <typename T>
923  inline T nequal_impl(const T v0, const T v1, int_type_tag)
924  {
925  return (v0 != v1) ? 1 : 0;
926  }
927 
928  template <typename T>
929  inline T modulus_impl(const T v0, const T v1, real_type_tag)
930  {
931  return std::fmod(v0,v1);
932  }
933 
934  template <typename T>
935  inline T modulus_impl(const T v0, const T v1, int_type_tag)
936  {
937  return v0 % v1;
938  }
939 
940  template <typename T>
941  inline T pow_impl(const T v0, const T v1, real_type_tag)
942  {
943  return std::pow(v0,v1);
944  }
945 
946  template <typename T>
947  inline T pow_impl(const T v0, const T v1, int_type_tag)
948  {
949  return std::pow(static_cast<double>(v0),static_cast<double>(v1));
950  }
951 
952  template <typename T>
953  inline T logn_impl(const T v0, const T v1, real_type_tag)
954  {
955  return std::log(v0) / std::log(v1);
956  }
957 
958  template <typename T>
959  inline T logn_impl(const T v0, const T v1, int_type_tag)
960  {
961  return static_cast<T>(logn_impl<double>(static_cast<double>(v0),static_cast<double>(v1),real_type_tag()));
962  }
963 
964  template <typename T>
965  inline T log1p_impl(const T v, real_type_tag)
966  {
967  if (v > T(-1))
968  {
969  if (abs_impl(v,real_type_tag()) > T(0.0001))
970  {
971  return std::log(T(1) + v);
972  }
973  else
974  return (T(-0.5) * v + T(1)) * v;
975  }
976  else
977  return std::numeric_limits<T>::quiet_NaN();
978  }
979 
980  template <typename T>
981  inline T log1p_impl(const T v, int_type_tag)
982  {
983  if (v > T(-1))
984  {
985  return std::log(T(1) + v);
986  }
987  else
988  return std::numeric_limits<T>::quiet_NaN();
989  }
990 
991  template <typename T>
992  inline T root_impl(const T v0, const T v1, real_type_tag)
993  {
994  if (v1 < T(0))
995  return std::numeric_limits<T>::quiet_NaN();
996 
997  const std::size_t n = static_cast<std::size_t>(v1);
998 
999  if ((v0 < T(0)) && (0 == (n % 2)))
1000  return std::numeric_limits<T>::quiet_NaN();
1001 
1002  return std::pow(v0, T(1) / n);
1003  }
1004 
1005  template <typename T>
1006  inline T root_impl(const T v0, const T v1, int_type_tag)
1007  {
1008  return root_impl<double>(static_cast<double>(v0),static_cast<double>(v1),real_type_tag());
1009  }
1010 
1011  template <typename T>
1012  inline T round_impl(const T v, real_type_tag)
1013  {
1014  return ((v < T(0)) ? std::ceil(v - T(0.5)) : std::floor(v + T(0.5)));
1015  }
1016 
1017  template <typename T>
1018  inline T roundn_impl(const T v0, const T v1, real_type_tag)
1019  {
1020  const int index = std::max<int>(0, std::min<int>(pow10_size - 1, (int)std::floor(v1)));
1021  const T p10 = T(pow10[index]);
1022 
1023  if (v0 < T(0))
1024  return T(std::ceil ((v0 * p10) - T(0.5)) / p10);
1025  else
1026  return T(std::floor((v0 * p10) + T(0.5)) / p10);
1027  }
1028 
1029  template <typename T>
1030  inline T roundn_impl(const T v0, const T, int_type_tag)
1031  {
1032  return v0;
1033  }
1034 
1035  template <typename T>
1036  inline T hypot_impl(const T v0, const T v1, real_type_tag)
1037  {
1038  return std::sqrt((v0 * v0) + (v1 * v1));
1039  }
1040 
1041  template <typename T>
1042  inline T hypot_impl(const T v0, const T v1, int_type_tag)
1043  {
1044  return static_cast<T>(std::sqrt(static_cast<double>((v0 * v0) + (v1 * v1))));
1045  }
1046 
1047  template <typename T>
1048  inline T atan2_impl(const T v0, const T v1, real_type_tag)
1049  {
1050  return std::atan2(v0,v1);
1051  }
1052 
1053  template <typename T>
1054  inline T atan2_impl(const T, const T, int_type_tag)
1055  {
1056  return 0;
1057  }
1058 
1059  template <typename T>
1060  inline T shr_impl(const T v0, const T v1, real_type_tag)
1061  {
1062  return v0 * (T(1) / std::pow(T(2),static_cast<T>(static_cast<int>(v1))));
1063  }
1064 
1065  template <typename T>
1066  inline T shr_impl(const T v0, const T v1, int_type_tag)
1067  {
1068  return v0 >> v1;
1069  }
1070 
1071  template <typename T>
1072  inline T shl_impl(const T v0, const T v1, real_type_tag)
1073  {
1074  return v0 * std::pow(T(2),static_cast<T>(static_cast<int>(v1)));
1075  }
1076 
1077  template <typename T>
1078  inline T shl_impl(const T v0, const T v1, int_type_tag)
1079  {
1080  return v0 << v1;
1081  }
1082 
1083  template <typename T>
1084  inline T sgn_impl(const T v, real_type_tag)
1085  {
1086  if (v > T(0)) return T(+1);
1087  else if (v < T(0)) return T(-1);
1088  else return T( 0);
1089  }
1090 
1091  template <typename T>
1092  inline T sgn_impl(const T v, int_type_tag)
1093  {
1094  if (v > T(0)) return T(+1);
1095  else if (v < T(0)) return T(-1);
1096  else return T( 0);
1097  }
1098 
1099  template <typename T>
1100  inline T and_impl(const T v0, const T v1, real_type_tag)
1101  {
1102  return (is_true_impl(v0) && is_true_impl(v1)) ? T(1) : T(0);
1103  }
1104 
1105  template <typename T>
1106  inline T and_impl(const T v0, const T v1, int_type_tag)
1107  {
1108  return v0 && v1;
1109  }
1110 
1111  template <typename T>
1112  inline T nand_impl(const T v0, const T v1, real_type_tag)
1113  {
1114  return (is_false_impl(v0) || is_false_impl(v1)) ? T(1) : T(0);
1115  }
1116 
1117  template <typename T>
1118  inline T nand_impl(const T v0, const T v1, int_type_tag)
1119  {
1120  return !(v0 && v1);
1121  }
1122 
1123  template <typename T>
1124  inline T or_impl(const T v0, const T v1, real_type_tag)
1125  {
1126  return (is_true_impl(v0) || is_true_impl(v1)) ? T(1) : T(0);
1127  }
1128 
1129  template <typename T>
1130  inline T or_impl(const T v0, const T v1, int_type_tag)
1131  {
1132  return (v0 || v1);
1133  }
1134 
1135  template <typename T>
1136  inline T nor_impl(const T v0, const T v1, real_type_tag)
1137  {
1138  return (is_false_impl(v0) && is_false_impl(v1)) ? T(1) : T(0);
1139  }
1140 
1141  template <typename T>
1142  inline T nor_impl(const T v0, const T v1, int_type_tag)
1143  {
1144  return !(v0 || v1);
1145  }
1146 
1147  template <typename T>
1148  inline T xor_impl(const T v0, const T v1, real_type_tag)
1149  {
1150  return (is_false_impl(v0) != is_false_impl(v1)) ? T(1) : T(0);
1151  }
1152 
1153  template <typename T>
1154  inline T xor_impl(const T v0, const T v1, int_type_tag)
1155  {
1156  return v0 ^ v1;
1157  }
1158 
1159  template <typename T>
1160  inline T xnor_impl(const T v0, const T v1, real_type_tag)
1161  {
1162  const bool v0_true = is_true_impl(v0);
1163  const bool v1_true = is_true_impl(v1);
1164 
1165  if ((v0_true && v1_true) || (!v0_true && !v1_true))
1166  return T(1);
1167  else
1168  return T(0);
1169  }
1170 
1171  template <typename T>
1172  inline T xnor_impl(const T v0, const T v1, int_type_tag)
1173  {
1174  const bool v0_true = is_true_impl(v0);
1175  const bool v1_true = is_true_impl(v1);
1176 
1177  if ((v0_true && v1_true) || (!v0_true && !v1_true))
1178  return T(1);
1179  else
1180  return T(0);
1181  }
1182 
1183  #if (defined(_MSC_VER) && (_MSC_VER >= 1900)) || !defined(_MSC_VER)
1184  #define exprtk_define_erf(TT,impl) \
1185  inline TT erf_impl(TT v) { return impl(v); } \
1186 
1187  exprtk_define_erf( float,::erff)
1188  exprtk_define_erf( double,::erf )
1189  exprtk_define_erf(long double,::erfl)
1190  #undef exprtk_define_erf
1191  #endif
1192 
1193  template <typename T>
1194  inline T erf_impl(T v, real_type_tag)
1195  {
1196  #if defined(_MSC_VER) && (_MSC_VER < 1900)
1197  // Credits: Abramowitz & Stegun Equations 7.1.25-28
1198  static const T c[] = {
1199  T( 1.26551223), T(1.00002368),
1200  T( 0.37409196), T(0.09678418),
1201  T(-0.18628806), T(0.27886807),
1202  T(-1.13520398), T(1.48851587),
1203  T(-0.82215223), T(0.17087277)
1204  };
1205 
1206  const T t = T(1) / (T(1) + T(0.5) * abs_impl(v,real_type_tag()));
1207 
1208  T result = T(1) - t * std::exp((-v * v) -
1209  c[0] + t * (c[1] + t *
1210  (c[2] + t * (c[3] + t *
1211  (c[4] + t * (c[5] + t *
1212  (c[6] + t * (c[7] + t *
1213  (c[8] + t * (c[9]))))))))));
1214 
1215  return (v >= T(0)) ? result : -result;
1216  #else
1217  return erf_impl(v);
1218  #endif
1219  }
1220 
1221  template <typename T>
1222  inline T erf_impl(T v, int_type_tag)
1223  {
1224  return erf_impl(static_cast<double>(v),real_type_tag());
1225  }
1226 
1227  #if (defined(_MSC_VER) && (_MSC_VER >= 1900)) || !defined(_MSC_VER)
1228  #define exprtk_define_erfc(TT,impl) \
1229  inline TT erfc_impl(TT v) { return impl(v); } \
1230 
1231  exprtk_define_erfc( float,::erfcf)
1232  exprtk_define_erfc( double,::erfc )
1233  exprtk_define_erfc(long double,::erfcl)
1234  #undef exprtk_define_erfc
1235  #endif
1236 
1237  template <typename T>
1238  inline T erfc_impl(T v, real_type_tag)
1239  {
1240  #if defined(_MSC_VER) && (_MSC_VER < 1900)
1241  return T(1) - erf_impl(v,real_type_tag());
1242  #else
1243  return erfc_impl(v);
1244  #endif
1245  }
1246 
1247  template <typename T>
1248  inline T erfc_impl(T v, int_type_tag)
1249  {
1250  return erfc_impl(static_cast<double>(v),real_type_tag());
1251  }
1252 
1253  template <typename T>
1255  {
1256  T cnd = T(0.5) * (T(1) + erf_impl(
1257  abs_impl(v,real_type_tag()) /
1259  return (v < T(0)) ? (T(1) - cnd) : cnd;
1260  }
1261 
1262  template <typename T>
1263  inline T ncdf_impl(T v, int_type_tag)
1264  {
1265  return ncdf_impl(static_cast<double>(v),real_type_tag());
1266  }
1267 
1268  template <typename T>
1270  {
1271  if (std::abs(v) >= std::numeric_limits<T>::epsilon())
1272  return(std::sin(v) / v);
1273  else
1274  return T(1);
1275  }
1276 
1277  template <typename T>
1278  inline T sinc_impl(T v, int_type_tag)
1279  {
1280  return sinc_impl(static_cast<double>(v),real_type_tag());
1281  }
1282 
1283  template <typename T> inline T acos_impl(const T v, real_type_tag) { return std::acos (v); }
1284  template <typename T> inline T acosh_impl(const T v, real_type_tag) { return std::log(v + std::sqrt((v * v) - T(1))); }
1285  template <typename T> inline T asin_impl(const T v, real_type_tag) { return std::asin (v); }
1286  template <typename T> inline T asinh_impl(const T v, real_type_tag) { return std::log(v + std::sqrt((v * v) + T(1))); }
1287  template <typename T> inline T atan_impl(const T v, real_type_tag) { return std::atan (v); }
1288  template <typename T> inline T atanh_impl(const T v, real_type_tag) { return (std::log(T(1) + v) - std::log(T(1) - v)) / T(2); }
1289  template <typename T> inline T ceil_impl(const T v, real_type_tag) { return std::ceil (v); }
1290  template <typename T> inline T cos_impl(const T v, real_type_tag) { return std::cos (v); }
1291  template <typename T> inline T cosh_impl(const T v, real_type_tag) { return std::cosh (v); }
1292  template <typename T> inline T exp_impl(const T v, real_type_tag) { return std::exp (v); }
1293  template <typename T> inline T floor_impl(const T v, real_type_tag) { return std::floor(v); }
1294  template <typename T> inline T log_impl(const T v, real_type_tag) { return std::log (v); }
1295  template <typename T> inline T log10_impl(const T v, real_type_tag) { return std::log10(v); }
1296  template <typename T> inline T log2_impl(const T v, real_type_tag) { return std::log(v)/T(numeric::constant::log2); }
1297  template <typename T> inline T neg_impl(const T v, real_type_tag) { return -v; }
1298  template <typename T> inline T pos_impl(const T v, real_type_tag) { return +v; }
1299  template <typename T> inline T sin_impl(const T v, real_type_tag) { return std::sin (v); }
1300  template <typename T> inline T sinh_impl(const T v, real_type_tag) { return std::sinh (v); }
1301  template <typename T> inline T sqrt_impl(const T v, real_type_tag) { return std::sqrt (v); }
1302  template <typename T> inline T tan_impl(const T v, real_type_tag) { return std::tan (v); }
1303  template <typename T> inline T tanh_impl(const T v, real_type_tag) { return std::tanh (v); }
1304  template <typename T> inline T cot_impl(const T v, real_type_tag) { return T(1) / std::tan(v); }
1305  template <typename T> inline T sec_impl(const T v, real_type_tag) { return T(1) / std::cos(v); }
1306  template <typename T> inline T csc_impl(const T v, real_type_tag) { return T(1) / std::sin(v); }
1307  template <typename T> inline T r2d_impl(const T v, real_type_tag) { return (v * T(numeric::constant::_180_pi)); }
1308  template <typename T> inline T d2r_impl(const T v, real_type_tag) { return (v * T(numeric::constant::pi_180)); }
1309  template <typename T> inline T d2g_impl(const T v, real_type_tag) { return (v * T(20.0/9.0)); }
1310  template <typename T> inline T g2d_impl(const T v, real_type_tag) { return (v * T(9.0/20.0)); }
1311  template <typename T> inline T notl_impl(const T v, real_type_tag) { return (std::not_equal_to<T>()(T(0),v) ? T(0) : T(1)); }
1312  template <typename T> inline T frac_impl(const T v, real_type_tag) { return (v - static_cast<long long>(v)); }
1313  template <typename T> inline T trunc_impl(const T v, real_type_tag) { return T(static_cast<long long>(v)); }
1314 
1315  template <typename T> inline T const_pi_impl(real_type_tag) { return T(numeric::constant::pi); }
1316  template <typename T> inline T const_e_impl (real_type_tag) { return T(numeric::constant::e); }
1317 
1318  template <typename T> inline T abs_impl(const T v, int_type_tag) { return ((v >= T(0)) ? v : -v); }
1319  template <typename T> inline T exp_impl(const T v, int_type_tag) { return std::exp (v); }
1320  template <typename T> inline T log_impl(const T v, int_type_tag) { return std::log (v); }
1321  template <typename T> inline T log10_impl(const T v, int_type_tag) { return std::log10(v); }
1322  template <typename T> inline T log2_impl(const T v, int_type_tag) { return std::log(v)/T(numeric::constant::log2); }
1323  template <typename T> inline T neg_impl(const T v, int_type_tag) { return -v; }
1324  template <typename T> inline T pos_impl(const T v, int_type_tag) { return +v; }
1325  template <typename T> inline T ceil_impl(const T v, int_type_tag) { return v; }
1326  template <typename T> inline T floor_impl(const T v, int_type_tag) { return v; }
1327  template <typename T> inline T round_impl(const T v, int_type_tag) { return v; }
1328  template <typename T> inline T notl_impl(const T v, int_type_tag) { return !v; }
1329  template <typename T> inline T sqrt_impl(const T v, int_type_tag) { return std::sqrt (v); }
1330  template <typename T> inline T frac_impl(const T , int_type_tag) { return T(0); }
1331  template <typename T> inline T trunc_impl(const T v, int_type_tag) { return v; }
1332  template <typename T> inline T acos_impl(const T , int_type_tag) { return std::numeric_limits<T>::quiet_NaN(); }
1333  template <typename T> inline T acosh_impl(const T , int_type_tag) { return std::numeric_limits<T>::quiet_NaN(); }
1334  template <typename T> inline T asin_impl(const T , int_type_tag) { return std::numeric_limits<T>::quiet_NaN(); }
1335  template <typename T> inline T asinh_impl(const T , int_type_tag) { return std::numeric_limits<T>::quiet_NaN(); }
1336  template <typename T> inline T atan_impl(const T , int_type_tag) { return std::numeric_limits<T>::quiet_NaN(); }
1337  template <typename T> inline T atanh_impl(const T , int_type_tag) { return std::numeric_limits<T>::quiet_NaN(); }
1338  template <typename T> inline T cos_impl(const T , int_type_tag) { return std::numeric_limits<T>::quiet_NaN(); }
1339  template <typename T> inline T cosh_impl(const T , int_type_tag) { return std::numeric_limits<T>::quiet_NaN(); }
1340  template <typename T> inline T sin_impl(const T , int_type_tag) { return std::numeric_limits<T>::quiet_NaN(); }
1341  template <typename T> inline T sinh_impl(const T , int_type_tag) { return std::numeric_limits<T>::quiet_NaN(); }
1342  template <typename T> inline T tan_impl(const T , int_type_tag) { return std::numeric_limits<T>::quiet_NaN(); }
1343  template <typename T> inline T tanh_impl(const T , int_type_tag) { return std::numeric_limits<T>::quiet_NaN(); }
1344  template <typename T> inline T cot_impl(const T , int_type_tag) { return std::numeric_limits<T>::quiet_NaN(); }
1345  template <typename T> inline T sec_impl(const T , int_type_tag) { return std::numeric_limits<T>::quiet_NaN(); }
1346  template <typename T> inline T csc_impl(const T , int_type_tag) { return std::numeric_limits<T>::quiet_NaN(); }
1347 
1348  template <typename T>
1349  inline bool is_integer_impl(const T& v, real_type_tag)
1350  {
1351  return std::equal_to<T>()(T(0),std::fmod(v,T(1)));
1352  }
1353 
1354  template <typename T>
1355  inline bool is_integer_impl(const T&, int_type_tag)
1356  {
1357  return true;
1358  }
1359  }
1360 
1361  template <typename Type>
1362  struct numeric_info { enum { length = 0, size = 32, bound_length = 0, min_exp = 0, max_exp = 0 }; };
1363 
1364  template<> struct numeric_info<int> { enum { length = 10, size = 16, bound_length = 9}; };
1365  template<> struct numeric_info<float> { enum { min_exp = -38, max_exp = +38}; };
1366  template<> struct numeric_info<double> { enum { min_exp = -308, max_exp = +308}; };
1367  template<> struct numeric_info<long double> { enum { min_exp = -308, max_exp = +308}; };
1368 
1369  template <typename T>
1370  inline int to_int32(const T v)
1371  {
1372  const typename details::number_type<T>::type num_type;
1373  return to_int32_impl(v, num_type);
1374  }
1375 
1376  template <typename T>
1377  inline long long int to_int64(const T v)
1378  {
1379  const typename details::number_type<T>::type num_type;
1380  return to_int64_impl(v, num_type);
1381  }
1382 
1383  template <typename T>
1384  inline bool is_nan(const T v)
1385  {
1386  const typename details::number_type<T>::type num_type;
1387  return is_nan_impl(v, num_type);
1388  }
1389 
1390  template <typename T>
1391  inline T min(const T v0, const T v1)
1392  {
1393  const typename details::number_type<T>::type num_type;
1394  return min_impl(v0, v1, num_type);
1395  }
1396 
1397  template <typename T>
1398  inline T max(const T v0, const T v1)
1399  {
1400  const typename details::number_type<T>::type num_type;
1401  return max_impl(v0, v1, num_type);
1402  }
1403 
1404  template <typename T>
1405  inline T equal(const T v0, const T v1)
1406  {
1407  const typename details::number_type<T>::type num_type;
1408  return equal_impl(v0, v1, num_type);
1409  }
1410 
1411  template <typename T>
1412  inline T nequal(const T v0, const T v1)
1413  {
1414  const typename details::number_type<T>::type num_type;
1415  return nequal_impl(v0, v1, num_type);
1416  }
1417 
1418  template <typename T>
1419  inline T modulus(const T v0, const T v1)
1420  {
1421  const typename details::number_type<T>::type num_type;
1422  return modulus_impl(v0, v1, num_type);
1423  }
1424 
1425  template <typename T>
1426  inline T pow(const T v0, const T v1)
1427  {
1428  const typename details::number_type<T>::type num_type;
1429  return pow_impl(v0, v1, num_type);
1430  }
1431 
1432  template <typename T>
1433  inline T logn(const T v0, const T v1)
1434  {
1435  const typename details::number_type<T>::type num_type;
1436  return logn_impl(v0, v1, num_type);
1437  }
1438 
1439  template <typename T>
1440  inline T root(const T v0, const T v1)
1441  {
1442  const typename details::number_type<T>::type num_type;
1443  return root_impl(v0, v1, num_type);
1444  }
1445 
1446  template <typename T>
1447  inline T roundn(const T v0, const T v1)
1448  {
1449  const typename details::number_type<T>::type num_type;
1450  return roundn_impl(v0, v1, num_type);
1451  }
1452 
1453  template <typename T>
1454  inline T hypot(const T v0, const T v1)
1455  {
1456  const typename details::number_type<T>::type num_type;
1457  return hypot_impl(v0, v1, num_type);
1458  }
1459 
1460  template <typename T>
1461  inline T atan2(const T v0, const T v1)
1462  {
1463  const typename details::number_type<T>::type num_type;
1464  return atan2_impl(v0, v1, num_type);
1465  }
1466 
1467  template <typename T>
1468  inline T shr(const T v0, const T v1)
1469  {
1470  const typename details::number_type<T>::type num_type;
1471  return shr_impl(v0, v1, num_type);
1472  }
1473 
1474  template <typename T>
1475  inline T shl(const T v0, const T v1)
1476  {
1477  const typename details::number_type<T>::type num_type;
1478  return shl_impl(v0, v1, num_type);
1479  }
1480 
1481  template <typename T>
1482  inline T and_opr(const T v0, const T v1)
1483  {
1484  const typename details::number_type<T>::type num_type;
1485  return and_impl(v0, v1, num_type);
1486  }
1487 
1488  template <typename T>
1489  inline T nand_opr(const T v0, const T v1)
1490  {
1491  const typename details::number_type<T>::type num_type;
1492  return nand_impl(v0, v1, num_type);
1493  }
1494 
1495  template <typename T>
1496  inline T or_opr(const T v0, const T v1)
1497  {
1498  const typename details::number_type<T>::type num_type;
1499  return or_impl(v0, v1, num_type);
1500  }
1501 
1502  template <typename T>
1503  inline T nor_opr(const T v0, const T v1)
1504  {
1505  const typename details::number_type<T>::type num_type;
1506  return nor_impl(v0, v1, num_type);
1507  }
1508 
1509  template <typename T>
1510  inline T xor_opr(const T v0, const T v1)
1511  {
1512  const typename details::number_type<T>::type num_type;
1513  return xor_impl(v0, v1, num_type);
1514  }
1515 
1516  template <typename T>
1517  inline T xnor_opr(const T v0, const T v1)
1518  {
1519  const typename details::number_type<T>::type num_type;
1520  return xnor_impl(v0, v1, num_type);
1521  }
1522 
1523  template <typename T>
1524  inline bool is_integer(const T v)
1525  {
1526  const typename details::number_type<T>::type num_type;
1527  return is_integer_impl(v, num_type);
1528  }
1529 
1530  template <typename T, unsigned int N>
1531  struct fast_exp
1532  {
1533  static inline T result(T v)
1534  {
1535  unsigned int k = N;
1536  T l = T(1);
1537 
1538  while (k)
1539  {
1540  if (k & 1)
1541  {
1542  l *= v;
1543  --k;
1544  }
1545 
1546  v *= v;
1547  k >>= 1;
1548  }
1549 
1550  return l;
1551  }
1552  };
1553 
1554  template <typename T> struct fast_exp<T,10> { static inline T result(T v) { T v_5 = fast_exp<T,5>::result(v); return v_5 * v_5; } };
1555  template <typename T> struct fast_exp<T, 9> { static inline T result(T v) { return fast_exp<T,8>::result(v) * v; } };
1556  template <typename T> struct fast_exp<T, 8> { static inline T result(T v) { T v_4 = fast_exp<T,4>::result(v); return v_4 * v_4; } };
1557  template <typename T> struct fast_exp<T, 7> { static inline T result(T v) { return fast_exp<T,6>::result(v) * v; } };
1558  template <typename T> struct fast_exp<T, 6> { static inline T result(T v) { T v_3 = fast_exp<T,3>::result(v); return v_3 * v_3; } };
1559  template <typename T> struct fast_exp<T, 5> { static inline T result(T v) { return fast_exp<T,4>::result(v) * v; } };
1560  template <typename T> struct fast_exp<T, 4> { static inline T result(T v) { T v_2 = v * v; return v_2 * v_2; } };
1561  template <typename T> struct fast_exp<T, 3> { static inline T result(T v) { return v * v * v; } };
1562  template <typename T> struct fast_exp<T, 2> { static inline T result(T v) { return v * v; } };
1563  template <typename T> struct fast_exp<T, 1> { static inline T result(T v) { return v; } };
1564  template <typename T> struct fast_exp<T, 0> { static inline T result(T ) { return T(1); } };
1565 
1566  #define exprtk_define_unary_function(FunctionName) \
1567  template <typename T> \
1568  inline T FunctionName (const T v) \
1569  { \
1570  const typename details::number_type<T>::type num_type; \
1571  return FunctionName##_impl(v,num_type); \
1572  } \
1573 
1614  #undef exprtk_define_unary_function
1615  }
1616 
1617  template <typename T>
1618  inline T compute_pow10(T d, const int exponent)
1619  {
1620  static const double fract10[] =
1621  {
1622  0.0,
1623  1.0E+001, 1.0E+002, 1.0E+003, 1.0E+004, 1.0E+005, 1.0E+006, 1.0E+007, 1.0E+008, 1.0E+009, 1.0E+010,
1624  1.0E+011, 1.0E+012, 1.0E+013, 1.0E+014, 1.0E+015, 1.0E+016, 1.0E+017, 1.0E+018, 1.0E+019, 1.0E+020,
1625  1.0E+021, 1.0E+022, 1.0E+023, 1.0E+024, 1.0E+025, 1.0E+026, 1.0E+027, 1.0E+028, 1.0E+029, 1.0E+030,
1626  1.0E+031, 1.0E+032, 1.0E+033, 1.0E+034, 1.0E+035, 1.0E+036, 1.0E+037, 1.0E+038, 1.0E+039, 1.0E+040,
1627  1.0E+041, 1.0E+042, 1.0E+043, 1.0E+044, 1.0E+045, 1.0E+046, 1.0E+047, 1.0E+048, 1.0E+049, 1.0E+050,
1628  1.0E+051, 1.0E+052, 1.0E+053, 1.0E+054, 1.0E+055, 1.0E+056, 1.0E+057, 1.0E+058, 1.0E+059, 1.0E+060,
1629  1.0E+061, 1.0E+062, 1.0E+063, 1.0E+064, 1.0E+065, 1.0E+066, 1.0E+067, 1.0E+068, 1.0E+069, 1.0E+070,
1630  1.0E+071, 1.0E+072, 1.0E+073, 1.0E+074, 1.0E+075, 1.0E+076, 1.0E+077, 1.0E+078, 1.0E+079, 1.0E+080,
1631  1.0E+081, 1.0E+082, 1.0E+083, 1.0E+084, 1.0E+085, 1.0E+086, 1.0E+087, 1.0E+088, 1.0E+089, 1.0E+090,
1632  1.0E+091, 1.0E+092, 1.0E+093, 1.0E+094, 1.0E+095, 1.0E+096, 1.0E+097, 1.0E+098, 1.0E+099, 1.0E+100,
1633  1.0E+101, 1.0E+102, 1.0E+103, 1.0E+104, 1.0E+105, 1.0E+106, 1.0E+107, 1.0E+108, 1.0E+109, 1.0E+110,
1634  1.0E+111, 1.0E+112, 1.0E+113, 1.0E+114, 1.0E+115, 1.0E+116, 1.0E+117, 1.0E+118, 1.0E+119, 1.0E+120,
1635  1.0E+121, 1.0E+122, 1.0E+123, 1.0E+124, 1.0E+125, 1.0E+126, 1.0E+127, 1.0E+128, 1.0E+129, 1.0E+130,
1636  1.0E+131, 1.0E+132, 1.0E+133, 1.0E+134, 1.0E+135, 1.0E+136, 1.0E+137, 1.0E+138, 1.0E+139, 1.0E+140,
1637  1.0E+141, 1.0E+142, 1.0E+143, 1.0E+144, 1.0E+145, 1.0E+146, 1.0E+147, 1.0E+148, 1.0E+149, 1.0E+150,
1638  1.0E+151, 1.0E+152, 1.0E+153, 1.0E+154, 1.0E+155, 1.0E+156, 1.0E+157, 1.0E+158, 1.0E+159, 1.0E+160,
1639  1.0E+161, 1.0E+162, 1.0E+163, 1.0E+164, 1.0E+165, 1.0E+166, 1.0E+167, 1.0E+168, 1.0E+169, 1.0E+170,
1640  1.0E+171, 1.0E+172, 1.0E+173, 1.0E+174, 1.0E+175, 1.0E+176, 1.0E+177, 1.0E+178, 1.0E+179, 1.0E+180,
1641  1.0E+181, 1.0E+182, 1.0E+183, 1.0E+184, 1.0E+185, 1.0E+186, 1.0E+187, 1.0E+188, 1.0E+189, 1.0E+190,
1642  1.0E+191, 1.0E+192, 1.0E+193, 1.0E+194, 1.0E+195, 1.0E+196, 1.0E+197, 1.0E+198, 1.0E+199, 1.0E+200,
1643  1.0E+201, 1.0E+202, 1.0E+203, 1.0E+204, 1.0E+205, 1.0E+206, 1.0E+207, 1.0E+208, 1.0E+209, 1.0E+210,
1644  1.0E+211, 1.0E+212, 1.0E+213, 1.0E+214, 1.0E+215, 1.0E+216, 1.0E+217, 1.0E+218, 1.0E+219, 1.0E+220,
1645  1.0E+221, 1.0E+222, 1.0E+223, 1.0E+224, 1.0E+225, 1.0E+226, 1.0E+227, 1.0E+228, 1.0E+229, 1.0E+230,
1646  1.0E+231, 1.0E+232, 1.0E+233, 1.0E+234, 1.0E+235, 1.0E+236, 1.0E+237, 1.0E+238, 1.0E+239, 1.0E+240,
1647  1.0E+241, 1.0E+242, 1.0E+243, 1.0E+244, 1.0E+245, 1.0E+246, 1.0E+247, 1.0E+248, 1.0E+249, 1.0E+250,
1648  1.0E+251, 1.0E+252, 1.0E+253, 1.0E+254, 1.0E+255, 1.0E+256, 1.0E+257, 1.0E+258, 1.0E+259, 1.0E+260,
1649  1.0E+261, 1.0E+262, 1.0E+263, 1.0E+264, 1.0E+265, 1.0E+266, 1.0E+267, 1.0E+268, 1.0E+269, 1.0E+270,
1650  1.0E+271, 1.0E+272, 1.0E+273, 1.0E+274, 1.0E+275, 1.0E+276, 1.0E+277, 1.0E+278, 1.0E+279, 1.0E+280,
1651  1.0E+281, 1.0E+282, 1.0E+283, 1.0E+284, 1.0E+285, 1.0E+286, 1.0E+287, 1.0E+288, 1.0E+289, 1.0E+290,
1652  1.0E+291, 1.0E+292, 1.0E+293, 1.0E+294, 1.0E+295, 1.0E+296, 1.0E+297, 1.0E+298, 1.0E+299, 1.0E+300,
1653  1.0E+301, 1.0E+302, 1.0E+303, 1.0E+304, 1.0E+305, 1.0E+306, 1.0E+307, 1.0E+308
1654  };
1655 
1656  static const int fract10_size = static_cast<int>(sizeof(fract10) / sizeof(double));
1657 
1658  const int e = std::abs(exponent);
1659 
1660  if (exponent >= std::numeric_limits<T>::min_exponent10)
1661  {
1662  if (e < fract10_size)
1663  {
1664  if (exponent > 0)
1665  return T(d * fract10[e]);
1666  else
1667  return T(d / fract10[e]);
1668  }
1669  else
1670  return T(d * std::pow(10.0, 10.0 * exponent));
1671  }
1672  else
1673  {
1674  d /= T(fract10[ -std::numeric_limits<T>::min_exponent10]);
1675  return T(d / fract10[-exponent + std::numeric_limits<T>::min_exponent10]);
1676  }
1677  }
1678 
1679  template <typename Iterator, typename T>
1680  inline bool string_to_type_converter_impl_ref(Iterator& itr, const Iterator end, T& result)
1681  {
1682  if (itr == end)
1683  return false;
1684 
1685  const bool negative = ('-' == (*itr));
1686 
1687  if (negative || ('+' == (*itr)))
1688  {
1689  if (end == ++itr)
1690  return false;
1691  }
1692 
1693  static const uchar_t zero = static_cast<uchar_t>('0');
1694 
1695  while ((end != itr) && (zero == (*itr))) ++itr;
1696 
1697  bool return_result = true;
1698  unsigned int digit = 0;
1699  const std::size_t length = static_cast<std::size_t>(std::distance(itr,end));
1700 
1701  if (length <= 4)
1702  {
1704  switch (length)
1705  {
1706  #ifdef exprtk_use_lut
1707 
1708  #define exprtk_process_digit \
1709  if ((digit = details::digit_table[(int)*itr++]) < 10) \
1710  result = result * 10 + (digit); \
1711  else \
1712  { \
1713  return_result = false; \
1714  break; \
1715  } \
1716 
1717  #else
1718 
1719  #define exprtk_process_digit \
1720  if ((digit = (*itr++ - zero)) < 10) \
1721  result = result * T(10) + digit; \
1722  else \
1723  { \
1724  return_result = false; \
1725  break; \
1726  } \
1727 
1728  #endif
1729 
1730  case 4 : exprtk_process_digit
1731  case 3 : exprtk_process_digit
1732  case 2 : exprtk_process_digit
1733  case 1 : if ((digit = (*itr - zero))>= 10) { digit = 0; return_result = false; }
1734 
1735  #undef exprtk_process_digit
1736  }
1738  }
1739  else
1740  return_result = false;
1741 
1742  if (length && return_result)
1743  {
1744  result = result * 10 + static_cast<T>(digit);
1745  ++itr;
1746  }
1747 
1748  result = negative ? -result : result;
1749  return return_result;
1750  }
1751 
1752  template <typename Iterator, typename T>
1753  static inline bool parse_nan(Iterator& itr, const Iterator end, T& t)
1754  {
1755  typedef typename std::iterator_traits<Iterator>::value_type type;
1756 
1757  static const std::size_t nan_length = 3;
1758 
1759  if (std::distance(itr,end) != static_cast<int>(nan_length))
1760  return false;
1761 
1762  if (static_cast<type>('n') == (*itr))
1763  {
1764  if (
1765  (static_cast<type>('a') != *(itr + 1)) ||
1766  (static_cast<type>('n') != *(itr + 2))
1767  )
1768  {
1769  return false;
1770  }
1771  }
1772  else if (
1773  (static_cast<type>('A') != *(itr + 1)) ||
1774  (static_cast<type>('N') != *(itr + 2))
1775  )
1776  {
1777  return false;
1778  }
1779 
1780  t = std::numeric_limits<T>::quiet_NaN();
1781 
1782  return true;
1783  }
1784 
1785  template <typename Iterator, typename T>
1786  static inline bool parse_inf(Iterator& itr, const Iterator end, T& t, bool negative)
1787  {
1788  static const char_t inf_uc[] = "INFINITY";
1789  static const char_t inf_lc[] = "infinity";
1790  static const std::size_t inf_length = 8;
1791 
1792  const std::size_t length = static_cast<std::size_t>(std::distance(itr,end));
1793 
1794  if ((3 != length) && (inf_length != length))
1795  return false;
1796 
1797  char_cptr inf_itr = ('i' == (*itr)) ? inf_lc : inf_uc;
1798 
1799  while (end != itr)
1800  {
1801  if (*inf_itr == static_cast<char>(*itr))
1802  {
1803  ++itr;
1804  ++inf_itr;
1805  continue;
1806  }
1807  else
1808  return false;
1809  }
1810 
1811  if (negative)
1812  t = -std::numeric_limits<T>::infinity();
1813  else
1814  t = std::numeric_limits<T>::infinity();
1815 
1816  return true;
1817  }
1818 
1819  template <typename Iterator, typename T>
1820  inline bool string_to_real(Iterator& itr_external, const Iterator end, T& t, numeric::details::real_type_tag)
1821  {
1822  if (end == itr_external) return false;
1823 
1824  Iterator itr = itr_external;
1825 
1826  T d = T(0);
1827 
1828  const bool negative = ('-' == (*itr));
1829 
1830  if (negative || '+' == (*itr))
1831  {
1832  if (end == ++itr)
1833  return false;
1834  }
1835 
1836  bool instate = false;
1837 
1838  static const char zero = static_cast<uchar_t>('0');
1839 
1840  #define parse_digit_1(d) \
1841  if ((digit = (*itr - zero)) < 10) \
1842  { d = d * T(10) + digit; } \
1843  else \
1844  { break; } \
1845  if (end == ++itr) break; \
1846 
1847  #define parse_digit_2(d) \
1848  if ((digit = (*itr - zero)) < 10) \
1849  { d = d * T(10) + digit; } \
1850  else { break; } \
1851  ++itr; \
1852 
1853  if ('.' != (*itr))
1854  {
1855  const Iterator curr = itr;
1856 
1857  while ((end != itr) && (zero == (*itr))) ++itr;
1858 
1859  unsigned int digit;
1860 
1861  while (end != itr)
1862  {
1863  // Note: For 'physical' superscalar architectures it
1864  // is advised that the following loop be: 4xPD1 and 1xPD2
1865  #ifdef exprtk_enable_superscalar
1866  parse_digit_1(d)
1867  parse_digit_1(d)
1868  #endif
1869  parse_digit_1(d)
1870  parse_digit_1(d)
1871  parse_digit_2(d)
1872  }
1873 
1874  if (curr != itr) instate = true;
1875  }
1876 
1877  int exponent = 0;
1878 
1879  if (end != itr)
1880  {
1881  if ('.' == (*itr))
1882  {
1883  const Iterator curr = ++itr;
1884  unsigned int digit;
1885  T tmp_d = T(0);
1886 
1887  while (end != itr)
1888  {
1889  #ifdef exprtk_enable_superscalar
1890  parse_digit_1(tmp_d)
1891  parse_digit_1(tmp_d)
1892  parse_digit_1(tmp_d)
1893  #endif
1894  parse_digit_1(tmp_d)
1895  parse_digit_1(tmp_d)
1896  parse_digit_2(tmp_d)
1897  }
1898 
1899  if (curr != itr)
1900  {
1901  instate = true;
1902  d += compute_pow10(tmp_d,static_cast<int>(-std::distance(curr,itr)));
1903  }
1904 
1905  #undef parse_digit_1
1906  #undef parse_digit_2
1907  }
1908 
1909  if (end != itr)
1910  {
1911  typename std::iterator_traits<Iterator>::value_type c = (*itr);
1912 
1913  if (('e' == c) || ('E' == c))
1914  {
1915  int exp = 0;
1916 
1917  if (!details::string_to_type_converter_impl_ref(++itr, end, exp))
1918  {
1919  if (end == itr)
1920  return false;
1921  else
1922  c = (*itr);
1923  }
1924 
1925  exponent += exp;
1926  }
1927 
1928  if (end != itr)
1929  {
1930  if (('f' == c) || ('F' == c) || ('l' == c) || ('L' == c))
1931  ++itr;
1932  else if ('#' == c)
1933  {
1934  if (end == ++itr)
1935  return false;
1936  else if (('I' <= (*itr)) && ((*itr) <= 'n'))
1937  {
1938  if (('i' == (*itr)) || ('I' == (*itr)))
1939  {
1940  return parse_inf(itr, end, t, negative);
1941  }
1942  else if (('n' == (*itr)) || ('N' == (*itr)))
1943  {
1944  return parse_nan(itr, end, t);
1945  }
1946  else
1947  return false;
1948  }
1949  else
1950  return false;
1951  }
1952  else if (('I' <= (*itr)) && ((*itr) <= 'n'))
1953  {
1954  if (('i' == (*itr)) || ('I' == (*itr)))
1955  {
1956  return parse_inf(itr, end, t, negative);
1957  }
1958  else if (('n' == (*itr)) || ('N' == (*itr)))
1959  {
1960  return parse_nan(itr, end, t);
1961  }
1962  else
1963  return false;
1964  }
1965  else
1966  return false;
1967  }
1968  }
1969  }
1970 
1971  if ((end != itr) || (!instate))
1972  return false;
1973  else if (exponent)
1974  d = compute_pow10(d,exponent);
1975 
1976  t = static_cast<T>((negative) ? -d : d);
1977  return true;
1978  }
1979 
1980  template <typename T>
1981  inline bool string_to_real(const std::string& s, T& t)
1982  {
1983  const typename numeric::details::number_type<T>::type num_type;
1984 
1985  char_cptr begin = s.data();
1986  char_cptr end = s.data() + s.size();
1987 
1988  return string_to_real(begin, end, t, num_type);
1989  }
1990 
1991  template <typename T>
1992  struct functor_t
1993  {
1994  /*
1995  Note: The following definitions for Type, may require tweaking
1996  based on the compiler and target architecture. The benchmark
1997  should provide enough information to make the right choice.
1998  */
1999  //typedef T Type;
2000  //typedef const T Type;
2001  typedef const T& Type;
2002  typedef T& RefType;
2003  typedef T (*qfunc_t)(Type t0, Type t1, Type t2, Type t3);
2004  typedef T (*tfunc_t)(Type t0, Type t1, Type t2);
2005  typedef T (*bfunc_t)(Type t0, Type t1);
2006  typedef T (*ufunc_t)(Type t0);
2007  };
2008 
2009  } // namespace details
2010 
2011  namespace lexer
2012  {
2013  struct token
2014  {
2016  {
2017  e_none = 0, e_error = 1, e_err_symbol = 2,
2019  e_eof = 6, e_number = 7, e_symbol = 8,
2020  e_string = 9, e_assign = 10, e_addass = 11,
2021  e_subass = 12, e_mulass = 13, e_divass = 14,
2022  e_modass = 15, e_shr = 16, e_shl = 17,
2023  e_lte = 18, e_ne = 19, e_gte = 20,
2024  e_swap = 21, e_lt = '<', e_gt = '>',
2025  e_eq = '=', e_rbracket = ')', e_lbracket = '(',
2027  e_lcrlbracket = '{', e_comma = ',', e_add = '+',
2028  e_sub = '-', e_div = '/', e_mul = '*',
2029  e_mod = '%', e_pow = '^', e_colon = ':',
2031  };
2032 
2034  : type(e_none),
2035  value(""),
2036  position(std::numeric_limits<std::size_t>::max())
2037  {}
2038 
2039  void clear()
2040  {
2041  type = e_none;
2042  value = "";
2044  }
2045 
2046  template <typename Iterator>
2047  inline token& set_operator(const token_type tt,
2048  const Iterator begin, const Iterator end,
2049  const Iterator base_begin = Iterator(0))
2050  {
2051  type = tt;
2052  value.assign(begin,end);
2053  if (base_begin)
2054  position = static_cast<std::size_t>(std::distance(base_begin,begin));
2055  return (*this);
2056  }
2057 
2058  template <typename Iterator>
2059  inline token& set_symbol(const Iterator begin, const Iterator end, const Iterator base_begin = Iterator(0))
2060  {
2061  type = e_symbol;
2062  value.assign(begin,end);
2063  if (base_begin)
2064  position = static_cast<std::size_t>(std::distance(base_begin,begin));
2065  return (*this);
2066  }
2067 
2068  template <typename Iterator>
2069  inline token& set_numeric(const Iterator begin, const Iterator end, const Iterator base_begin = Iterator(0))
2070  {
2071  type = e_number;
2072  value.assign(begin,end);
2073  if (base_begin)
2074  position = static_cast<std::size_t>(std::distance(base_begin,begin));
2075  return (*this);
2076  }
2077 
2078  template <typename Iterator>
2079  inline token& set_string(const Iterator begin, const Iterator end, const Iterator base_begin = Iterator(0))
2080  {
2081  type = e_string;
2082  value.assign(begin,end);
2083  if (base_begin)
2084  position = static_cast<std::size_t>(std::distance(base_begin,begin));
2085  return (*this);
2086  }
2087 
2088  inline token& set_string(const std::string& s, const std::size_t p)
2089  {
2090  type = e_string;
2091  value = s;
2092  position = p;
2093  return (*this);
2094  }
2095 
2096  template <typename Iterator>
2097  inline token& set_error(const token_type et,
2098  const Iterator begin, const Iterator end,
2099  const Iterator base_begin = Iterator(0))
2100  {
2101  if (
2102  (e_error == et) ||
2103  (e_err_symbol == et) ||
2104  (e_err_number == et) ||
2105  (e_err_string == et) ||
2106  (e_err_sfunc == et)
2107  )
2108  {
2109  type = et;
2110  }
2111  else
2112  type = e_error;
2113 
2114  value.assign(begin,end);
2115 
2116  if (base_begin)
2117  position = static_cast<std::size_t>(std::distance(base_begin,begin));
2118 
2119  return (*this);
2120  }
2121 
2122  static inline std::string to_str(token_type t)
2123  {
2124  switch (t)
2125  {
2126  case e_none : return "NONE";
2127  case e_error : return "ERROR";
2128  case e_err_symbol : return "ERROR_SYMBOL";
2129  case e_err_number : return "ERROR_NUMBER";
2130  case e_err_string : return "ERROR_STRING";
2131  case e_eof : return "EOF";
2132  case e_number : return "NUMBER";
2133  case e_symbol : return "SYMBOL";
2134  case e_string : return "STRING";
2135  case e_assign : return ":=";
2136  case e_addass : return "+=";
2137  case e_subass : return "-=";
2138  case e_mulass : return "*=";
2139  case e_divass : return "/=";
2140  case e_modass : return "%=";
2141  case e_shr : return ">>";
2142  case e_shl : return "<<";
2143  case e_lte : return "<=";
2144  case e_ne : return "!=";
2145  case e_gte : return ">=";
2146  case e_lt : return "<";
2147  case e_gt : return ">";
2148  case e_eq : return "=";
2149  case e_rbracket : return ")";
2150  case e_lbracket : return "(";
2151  case e_rsqrbracket : return "]";
2152  case e_lsqrbracket : return "[";
2153  case e_rcrlbracket : return "}";
2154  case e_lcrlbracket : return "{";
2155  case e_comma : return ",";
2156  case e_add : return "+";
2157  case e_sub : return "-";
2158  case e_div : return "/";
2159  case e_mul : return "*";
2160  case e_mod : return "%";
2161  case e_pow : return "^";
2162  case e_colon : return ":";
2163  case e_ternary : return "?";
2164  case e_swap : return "<=>";
2165  default : return "UNKNOWN";
2166  }
2167  }
2168 
2169  inline bool is_error() const
2170  {
2171  return (
2172  (e_error == type) ||
2173  (e_err_symbol == type) ||
2174  (e_err_number == type) ||
2175  (e_err_string == type) ||
2176  (e_err_sfunc == type)
2177  );
2178  }
2179 
2181  std::string value;
2182  std::size_t position;
2183  };
2184 
2186  {
2187  public:
2188 
2189  typedef token token_t;
2190  typedef std::vector<token_t> token_list_t;
2191  typedef std::vector<token_t>::iterator token_list_itr_t;
2193 
2195  : base_itr_(0),
2196  s_itr_ (0),
2197  s_end_ (0)
2198  {
2199  clear();
2200  }
2201 
2202  inline void clear()
2203  {
2204  base_itr_ = 0;
2205  s_itr_ = 0;
2206  s_end_ = 0;
2207  token_list_.clear();
2208  token_itr_ = token_list_.end();
2209  store_token_itr_ = token_list_.end();
2210  }
2211 
2212  inline bool process(const std::string& str)
2213  {
2214  base_itr_ = str.data();
2215  s_itr_ = str.data();
2216  s_end_ = str.data() + str.size();
2217 
2219  token_list_.clear();
2220 
2221  while (!is_end(s_itr_))
2222  {
2223  scan_token();
2224 
2225  if (!token_list_.empty() && token_list_.back().is_error())
2226  return false;
2227  }
2228 
2229  return true;
2230  }
2231 
2232  inline bool empty() const
2233  {
2234  return token_list_.empty();
2235  }
2236 
2237  inline std::size_t size() const
2238  {
2239  return token_list_.size();
2240  }
2241 
2242  inline void begin()
2243  {
2244  token_itr_ = token_list_.begin();
2245  store_token_itr_ = token_list_.begin();
2246  }
2247 
2248  inline void store()
2249  {
2251  }
2252 
2253  inline void restore()
2254  {
2256  }
2257 
2259  {
2260  if (token_list_.end() != token_itr_)
2261  {
2262  return *token_itr_++;
2263  }
2264  else
2265  return eof_token_;
2266  }
2267 
2269  {
2270  if (token_list_.end() != token_itr_)
2271  {
2272  return *token_itr_;
2273  }
2274  else
2275  return eof_token_;
2276  }
2277 
2278  inline token_t& operator[](const std::size_t& index)
2279  {
2280  if (index < token_list_.size())
2281  return token_list_[index];
2282  else
2283  return eof_token_;
2284  }
2285 
2286  inline token_t operator[](const std::size_t& index) const
2287  {
2288  if (index < token_list_.size())
2289  return token_list_[index];
2290  else
2291  return eof_token_;
2292  }
2293 
2294  inline bool finished() const
2295  {
2296  return (token_list_.end() == token_itr_);
2297  }
2298 
2299  inline void insert_front(token_t::token_type tk_type)
2300  {
2301  if (
2302  !token_list_.empty() &&
2303  (token_list_.end() != token_itr_)
2304  )
2305  {
2306  token_t t = *token_itr_;
2307 
2308  t.type = tk_type;
2309  token_itr_ = token_list_.insert(token_itr_,t);
2310  }
2311  }
2312 
2313  inline std::string substr(const std::size_t& begin, const std::size_t& end)
2314  {
2315  const details::char_cptr begin_itr = ((base_itr_ + begin) < s_end_) ? (base_itr_ + begin) : s_end_;
2316  const details::char_cptr end_itr = ((base_itr_ + end) < s_end_) ? (base_itr_ + end) : s_end_;
2317 
2318  return std::string(begin_itr,end_itr);
2319  }
2320 
2321  inline std::string remaining() const
2322  {
2323  if (finished())
2324  return "";
2325  else if (token_list_.begin() != token_itr_)
2326  return std::string(base_itr_ + (token_itr_ - 1)->position,s_end_);
2327  else
2328  return std::string(base_itr_ + token_itr_->position,s_end_);
2329  }
2330 
2331  private:
2332 
2333  inline bool is_end(details::char_cptr itr)
2334  {
2335  return (s_end_ == itr);
2336  }
2337 
2339  {
2340  #ifndef exprtk_disable_comments
2341  const char_t c0 = *(itr + 0);
2342  const char_t c1 = *(itr + 1);
2343 
2344  if ('#' == c0)
2345  return true;
2346  else if (!is_end(itr + 1))
2347  {
2348  if (('/' == c0) && ('/' == c1)) return true;
2349  if (('/' == c0) && ('*' == c1)) return true;
2350  }
2351  #endif
2352  return false;
2353  }
2354 
2355  inline void skip_whitespace()
2356  {
2358  {
2359  ++s_itr_;
2360  }
2361  }
2362 
2363  inline void skip_comments()
2364  {
2365  #ifndef exprtk_disable_comments
2366  // The following comment styles are supported:
2367  // 1. // .... \n
2368  // 2. # .... \n
2369  // 3. /* .... */
2370  struct test
2371  {
2372  static inline bool comment_start(const char_t c0, const char_t c1, int& mode, int& incr)
2373  {
2374  mode = 0;
2375  if ('#' == c0) { mode = 1; incr = 1; }
2376  else if ('/' == c0)
2377  {
2378  if ('/' == c1) { mode = 1; incr = 2; }
2379  else if ('*' == c1) { mode = 2; incr = 2; }
2380  }
2381  return (0 != mode);
2382  }
2383 
2384  static inline bool comment_end(const char_t c0, const char_t c1, int& mode)
2385  {
2386  if (
2387  ((1 == mode) && ('\n' == c0)) ||
2388  ((2 == mode) && ( '*' == c0) && ('/' == c1))
2389  )
2390  {
2391  mode = 0;
2392  return true;
2393  }
2394  else
2395  return false;
2396  }
2397  };
2398 
2399  int mode = 0;
2400  int increment = 0;
2401 
2402  if (is_end(s_itr_))
2403  return;
2404  else if (!test::comment_start(*s_itr_, *(s_itr_ + 1), mode, increment))
2405  return;
2406 
2407  details::char_cptr cmt_start = s_itr_;
2408 
2409  s_itr_ += increment;
2410 
2411  while (!is_end(s_itr_))
2412  {
2413  if ((1 == mode) && test::comment_end(*s_itr_, 0, mode))
2414  {
2415  ++s_itr_;
2416  return;
2417  }
2418 
2419  if ((2 == mode))
2420  {
2421  if (!is_end((s_itr_ + 1)) && test::comment_end(*s_itr_, *(s_itr_ + 1), mode))
2422  {
2423  s_itr_ += 2;
2424  return;
2425  }
2426  }
2427 
2428  ++s_itr_;
2429  }
2430 
2431  if (2 == mode)
2432  {
2433  token_t t;
2434  t.set_error(token::e_error, cmt_start, cmt_start + mode, base_itr_);
2435  token_list_.push_back(t);
2436  }
2437  #endif
2438  }
2439 
2440  inline void scan_token()
2441  {
2443  {
2444  skip_whitespace();
2445  return;
2446  }
2447  else if (is_comment_start(s_itr_))
2448  {
2449  skip_comments();
2450  return;
2451  }
2452  else if (details::is_operator_char(*s_itr_))
2453  {
2454  scan_operator();
2455  return;
2456  }
2457  else if (details::is_letter(*s_itr_))
2458  {
2459  scan_symbol();
2460  return;
2461  }
2462  else if (details::is_digit((*s_itr_)) || ('.' == (*s_itr_)))
2463  {
2464  scan_number();
2465  return;
2466  }
2467  else if ('$' == (*s_itr_))
2468  {
2470  return;
2471  }
2472  #ifndef exprtk_disable_string_capabilities
2473  else if ('\'' == (*s_itr_))
2474  {
2475  scan_string();
2476  return;
2477  }
2478  #endif
2479  else if ('~' == (*s_itr_))
2480  {
2481  token_t t;
2482  t.set_symbol(s_itr_, s_itr_ + 1, base_itr_);
2483  token_list_.push_back(t);
2484  ++s_itr_;
2485  return;
2486  }
2487  else
2488  {
2489  token_t t;
2491  token_list_.push_back(t);
2492  ++s_itr_;
2493  }
2494  }
2495 
2496  inline void scan_operator()
2497  {
2498  token_t t;
2499 
2500  const char_t c0 = s_itr_[0];
2501 
2502  if (!is_end(s_itr_ + 1))
2503  {
2504  const char_t c1 = s_itr_[1];
2505 
2506  if (!is_end(s_itr_ + 2))
2507  {
2508  const char_t c2 = s_itr_[2];
2509 
2510  if ((c0 == '<') && (c1 == '=') && (c2 == '>'))
2511  {
2513  token_list_.push_back(t);
2514  s_itr_ += 3;
2515  return;
2516  }
2517  }
2518 
2520 
2521  if ((c0 == '<') && (c1 == '=')) ttype = token_t::e_lte;
2522  else if ((c0 == '>') && (c1 == '=')) ttype = token_t::e_gte;
2523  else if ((c0 == '<') && (c1 == '>')) ttype = token_t::e_ne;
2524  else if ((c0 == '!') && (c1 == '=')) ttype = token_t::e_ne;
2525  else if ((c0 == '=') && (c1 == '=')) ttype = token_t::e_eq;
2526  else if ((c0 == ':') && (c1 == '=')) ttype = token_t::e_assign;
2527  else if ((c0 == '<') && (c1 == '<')) ttype = token_t::e_shl;
2528  else if ((c0 == '>') && (c1 == '>')) ttype = token_t::e_shr;
2529  else if ((c0 == '+') && (c1 == '=')) ttype = token_t::e_addass;
2530  else if ((c0 == '-') && (c1 == '=')) ttype = token_t::e_subass;
2531  else if ((c0 == '*') && (c1 == '=')) ttype = token_t::e_mulass;
2532  else if ((c0 == '/') && (c1 == '=')) ttype = token_t::e_divass;
2533  else if ((c0 == '%') && (c1 == '=')) ttype = token_t::e_modass;
2534 
2535  if (token_t::e_none != ttype)
2536  {
2537  t.set_operator(ttype, s_itr_, s_itr_ + 2, base_itr_);
2538  token_list_.push_back(t);
2539  s_itr_ += 2;
2540  return;
2541  }
2542  }
2543 
2544  if ('<' == c0)
2546  else if ('>' == c0)
2548  else if (';' == c0)
2550  else if ('&' == c0)
2551  t.set_symbol(s_itr_, s_itr_ + 1, base_itr_);
2552  else if ('|' == c0)
2553  t.set_symbol(s_itr_, s_itr_ + 1, base_itr_);
2554  else
2556 
2557  token_list_.push_back(t);
2558  ++s_itr_;
2559  }
2560 
2561  inline void scan_symbol()
2562  {
2563  details::char_cptr initial_itr = s_itr_;
2564 
2565  while (!is_end(s_itr_))
2566  {
2567  if (!details::is_letter_or_digit(*s_itr_) && ('_' != (*s_itr_)))
2568  {
2569  if ('.' != (*s_itr_))
2570  break;
2571  /*
2572  Permit symbols that contain a 'dot'
2573  Allowed : abc.xyz, a123.xyz, abc.123, abc_.xyz a123_.xyz abc._123
2574  Disallowed: .abc, abc.<white-space>, abc.<eof>, abc.<operator +,-,*,/...>
2575  */
2576  if (
2577  (s_itr_ != initial_itr) &&
2578  !is_end(s_itr_ + 1) &&
2580  ('_' != (*(s_itr_ + 1)))
2581  )
2582  break;
2583  }
2584 
2585  ++s_itr_;
2586  }
2587 
2588  token_t t;
2589  t.set_symbol(initial_itr,s_itr_,base_itr_);
2590  token_list_.push_back(t);
2591  }
2592 
2593  inline void scan_number()
2594  {
2595  /*
2596  Attempt to match a valid numeric value in one of the following formats:
2597  (01) 123456
2598  (02) 123456.
2599  (03) 123.456
2600  (04) 123.456e3
2601  (05) 123.456E3
2602  (06) 123.456e+3
2603  (07) 123.456E+3
2604  (08) 123.456e-3
2605  (09) 123.456E-3
2606  (00) .1234
2607  (11) .1234e3
2608  (12) .1234E+3
2609  (13) .1234e+3
2610  (14) .1234E-3
2611  (15) .1234e-3
2612  */
2613 
2614  details::char_cptr initial_itr = s_itr_;
2615  bool dot_found = false;
2616  bool e_found = false;
2617  bool post_e_sign_found = false;
2618  bool post_e_digit_found = false;
2619  token_t t;
2620 
2621  while (!is_end(s_itr_))
2622  {
2623  if ('.' == (*s_itr_))
2624  {
2625  if (dot_found)
2626  {
2627  t.set_error(token::e_err_number, initial_itr, s_itr_, base_itr_);
2628  token_list_.push_back(t);
2629  return;
2630  }
2631 
2632  dot_found = true;
2633  ++s_itr_;
2634 
2635  continue;
2636  }
2637  else if ('e' == std::tolower(*s_itr_))
2638  {
2639  const char_t& c = *(s_itr_ + 1);
2640 
2641  if (is_end(s_itr_ + 1))
2642  {
2643  t.set_error(token::e_err_number, initial_itr, s_itr_, base_itr_);
2644  token_list_.push_back(t);
2645 
2646  return;
2647  }
2648  else if (
2649  ('+' != c) &&
2650  ('-' != c) &&
2651  !details::is_digit(c)
2652  )
2653  {
2654  t.set_error(token::e_err_number, initial_itr, s_itr_, base_itr_);
2655  token_list_.push_back(t);
2656 
2657  return;
2658  }
2659 
2660  e_found = true;
2661  ++s_itr_;
2662 
2663  continue;
2664  }
2665  else if (e_found && details::is_sign(*s_itr_) && !post_e_digit_found)
2666  {
2667  if (post_e_sign_found)
2668  {
2669  t.set_error(token::e_err_number, initial_itr, s_itr_, base_itr_);
2670  token_list_.push_back(t);
2671 
2672  return;
2673  }
2674 
2675  post_e_sign_found = true;
2676  ++s_itr_;
2677 
2678  continue;
2679  }
2680  else if (e_found && details::is_digit(*s_itr_))
2681  {
2682  post_e_digit_found = true;
2683  ++s_itr_;
2684 
2685  continue;
2686  }
2687  else if (('.' != (*s_itr_)) && !details::is_digit(*s_itr_))
2688  break;
2689  else
2690  ++s_itr_;
2691  }
2692 
2693  t.set_numeric(initial_itr, s_itr_, base_itr_);
2694  token_list_.push_back(t);
2695 
2696  return;
2697  }
2698 
2700  {
2701  details::char_cptr initial_itr = s_itr_;
2702  token_t t;
2703 
2704  // $fdd(x,x,x) = at least 11 chars
2705  if (std::distance(s_itr_,s_end_) < 11)
2706  {
2707  t.set_error(token::e_err_sfunc, initial_itr, s_itr_, base_itr_);
2708  token_list_.push_back(t);
2709 
2710  return;
2711  }
2712 
2713  if (
2714  !(('$' == *s_itr_) &&
2715  (details::imatch ('f',*(s_itr_ + 1))) &&
2716  (details::is_digit(*(s_itr_ + 2))) &&
2717  (details::is_digit(*(s_itr_ + 3))))
2718  )
2719  {
2720  t.set_error(token::e_err_sfunc, initial_itr, s_itr_, base_itr_);
2721  token_list_.push_back(t);
2722 
2723  return;
2724  }
2725 
2726  s_itr_ += 4; // $fdd = 4chars
2727 
2728  t.set_symbol(initial_itr, s_itr_, base_itr_);
2729  token_list_.push_back(t);
2730 
2731  return;
2732  }
2733 
2734  #ifndef exprtk_disable_string_capabilities
2735  inline void scan_string()
2736  {
2737  details::char_cptr initial_itr = s_itr_ + 1;
2738  token_t t;
2739 
2740  if (std::distance(s_itr_,s_end_) < 2)
2741  {
2743  token_list_.push_back(t);
2744  return;
2745  }
2746 
2747  ++s_itr_;
2748 
2749  bool escaped_found = false;
2750  bool escaped = false;
2751 
2752  while (!is_end(s_itr_))
2753  {
2754  if (!escaped && ('\\' == *s_itr_))
2755  {
2756  escaped_found = true;
2757  escaped = true;
2758  ++s_itr_;
2759 
2760  continue;
2761  }
2762  else if (!escaped)
2763  {
2764  if ('\'' == *s_itr_)
2765  break;
2766  }
2767  else if (escaped)
2768  {
2769  if (!is_end(s_itr_) && ('0' == *(s_itr_)))
2770  {
2771  /*
2772  Note: The following 'awkward' conditional is
2773  due to various broken msvc compilers.
2774  */
2775  #if defined(_MSC_VER) && (_MSC_VER == 1600)
2776  const bool within_range = !is_end(s_itr_ + 2) &&
2777  !is_end(s_itr_ + 3) ;
2778  #else
2779  const bool within_range = !is_end(s_itr_ + 1) &&
2780  !is_end(s_itr_ + 2) &&
2781  !is_end(s_itr_ + 3) ;
2782  #endif
2783 
2784  const bool x_seperator = ('x' == *(s_itr_ + 1)) ||
2785  ('X' == *(s_itr_ + 1)) ;
2786 
2787  const bool both_digits = details::is_hex_digit(*(s_itr_ + 2)) &&
2788  details::is_hex_digit(*(s_itr_ + 3)) ;
2789 
2790  if (!within_range || !x_seperator || !both_digits)
2791  {
2792  t.set_error(token::e_err_string, initial_itr, s_itr_, base_itr_);
2793  token_list_.push_back(t);
2794 
2795  return;
2796  }
2797  else
2798  s_itr_ += 3;
2799  }
2800 
2801  escaped = false;
2802  }
2803 
2804  ++s_itr_;
2805  }
2806 
2807  if (is_end(s_itr_))
2808  {
2809  t.set_error(token::e_err_string, initial_itr, s_itr_, base_itr_);
2810  token_list_.push_back(t);
2811 
2812  return;
2813  }
2814 
2815  if (!escaped_found)
2816  t.set_string(initial_itr, s_itr_, base_itr_);
2817  else
2818  {
2819  std::string parsed_string(initial_itr,s_itr_);
2820 
2821  details::cleanup_escapes(parsed_string);
2822 
2823  t.set_string(
2824  parsed_string,
2825  static_cast<std::size_t>(std::distance(base_itr_,initial_itr)));
2826  }
2827 
2828  token_list_.push_back(t);
2829  ++s_itr_;
2830 
2831  return;
2832  }
2833  #endif
2834 
2835  private:
2836 
2844 
2845  friend class token_scanner;
2846  friend class token_modifier;
2847  friend class token_inserter;
2848  friend class token_joiner;
2849  };
2850 
2852  {
2853  public:
2854 
2855  virtual void init() { }
2856  virtual void reset() { }
2857  virtual bool result() { return true; }
2858  virtual std::size_t process(generator&) { return 0; }
2859  virtual ~helper_interface() { }
2860  };
2861 
2863  {
2864  public:
2865 
2866  virtual ~token_scanner()
2867  {}
2868 
2869  explicit token_scanner(const std::size_t& stride)
2870  : stride_(stride)
2871  {
2872  if (stride > 4)
2873  {
2874  throw std::invalid_argument("token_scanner() - Invalid stride value");
2875  }
2876  }
2877 
2878  inline std::size_t process(generator& g)
2879  {
2880  if (g.token_list_.size() >= stride_)
2881  {
2882  for (std::size_t i = 0; i < (g.token_list_.size() - stride_ + 1); ++i)
2883  {
2884  token t;
2885 
2886  switch (stride_)
2887  {
2888  case 1 :
2889  {
2890  const token& t0 = g.token_list_[i];
2891 
2892  if (!operator()(t0))
2893  {
2894  return i;
2895  }
2896  }
2897  break;
2898 
2899  case 2 :
2900  {
2901  const token& t0 = g.token_list_[i ];
2902  const token& t1 = g.token_list_[i + 1];
2903 
2904  if (!operator()(t0, t1))
2905  {
2906  return i;
2907  }
2908  }
2909  break;
2910 
2911  case 3 :
2912  {
2913  const token& t0 = g.token_list_[i ];
2914  const token& t1 = g.token_list_[i + 1];
2915  const token& t2 = g.token_list_[i + 2];
2916 
2917  if (!operator()(t0, t1, t2))
2918  {
2919  return i;
2920  }
2921  }
2922  break;
2923 
2924  case 4 :
2925  {
2926  const token& t0 = g.token_list_[i ];
2927  const token& t1 = g.token_list_[i + 1];
2928  const token& t2 = g.token_list_[i + 2];
2929  const token& t3 = g.token_list_[i + 3];
2930 
2931  if (!operator()(t0, t1, t2, t3))
2932  {
2933  return i;
2934  }
2935  }
2936  break;
2937  }
2938  }
2939  }
2940 
2941  return (g.token_list_.size() - stride_ + 1);
2942  }
2943 
2944  virtual bool operator() (const token&)
2945  {
2946  return false;
2947  }
2948 
2949  virtual bool operator() (const token&, const token&)
2950  {
2951  return false;
2952  }
2953 
2954  virtual bool operator() (const token&, const token&, const token&)
2955  {
2956  return false;
2957  }
2958 
2959  virtual bool operator() (const token&, const token&, const token&, const token&)
2960  {
2961  return false;
2962  }
2963 
2964  private:
2965 
2966  const std::size_t stride_;
2967  };
2968 
2970  {
2971  public:
2972 
2973  inline std::size_t process(generator& g)
2974  {
2975  std::size_t changes = 0;
2976 
2977  for (std::size_t i = 0; i < g.token_list_.size(); ++i)
2978  {
2979  if (modify(g.token_list_[i])) changes++;
2980  }
2981 
2982  return changes;
2983  }
2984 
2985  virtual bool modify(token& t) = 0;
2986  };
2987 
2989  {
2990  public:
2991 
2992  explicit token_inserter(const std::size_t& stride)
2993  : stride_(stride)
2994  {
2995  if (stride > 5)
2996  {
2997  throw std::invalid_argument("token_inserter() - Invalid stride value");
2998  }
2999  }
3000 
3001  inline std::size_t process(generator& g)
3002  {
3003  if (g.token_list_.empty())
3004  return 0;
3005  else if (g.token_list_.size() < stride_)
3006  return 0;
3007 
3008  std::size_t changes = 0;
3009 
3010  for (std::size_t i = 0; i < (g.token_list_.size() - stride_ + 1); ++i)
3011  {
3012  int insert_index = -1;
3013  token t;
3014 
3015  switch (stride_)
3016  {
3017  case 1 : insert_index = insert(g.token_list_[i],t);
3018  break;
3019 
3020  case 2 : insert_index = insert(g.token_list_[i], g.token_list_[i + 1], t);
3021  break;
3022 
3023  case 3 : insert_index = insert(g.token_list_[i], g.token_list_[i + 1], g.token_list_[i + 2], t);
3024  break;
3025 
3026  case 4 : insert_index = insert(g.token_list_[i], g.token_list_[i + 1], g.token_list_[i + 2], g.token_list_[i + 3], t);
3027  break;
3028 
3029  case 5 : insert_index = insert(g.token_list_[i], g.token_list_[i + 1], g.token_list_[i + 2], g.token_list_[i + 3], g.token_list_[i + 4], t);
3030  break;
3031  }
3032 
3033  typedef std::iterator_traits<generator::token_list_t::iterator>::difference_type diff_t;
3034 
3035  if ((insert_index >= 0) && (insert_index <= (static_cast<int>(stride_) + 1)))
3036  {
3037  g.token_list_.insert(
3038  g.token_list_.begin() + static_cast<diff_t>(i + static_cast<std::size_t>(insert_index)), t);
3039 
3040  changes++;
3041  }
3042  }
3043 
3044  return changes;
3045  }
3046 
3047  #define token_inserter_empty_body \
3048  { \
3049  return -1; \
3050  } \
3051 
3052  inline virtual int insert(const token&, token&)
3054 
3055  inline virtual int insert(const token&, const token&, token&)
3057 
3058  inline virtual int insert(const token&, const token&, const token&, token&)
3060 
3061  inline virtual int insert(const token&, const token&, const token&, const token&, token&)
3063 
3064  inline virtual int insert(const token&, const token&, const token&, const token&, const token&, token&)
3066 
3067  #undef token_inserter_empty_body
3068 
3069  private:
3070 
3071  const std::size_t stride_;
3072  };
3073 
3075  {
3076  public:
3077 
3078  token_joiner(const std::size_t& stride)
3079  : stride_(stride)
3080  {}
3081 
3082  inline std::size_t process(generator& g)
3083  {
3084  if (g.token_list_.empty())
3085  return 0;
3086 
3087  switch (stride_)
3088  {
3089  case 2 : return process_stride_2(g);
3090  case 3 : return process_stride_3(g);
3091  default : return 0;
3092  }
3093  }
3094 
3095  virtual bool join(const token&, const token&, token&) { return false; }
3096  virtual bool join(const token&, const token&, const token&, token&) { return false; }
3097 
3098  private:
3099 
3100  inline std::size_t process_stride_2(generator& g)
3101  {
3102  typedef std::iterator_traits<generator::token_list_t::iterator>::difference_type diff_t;
3103 
3104  if (g.token_list_.size() < 2)
3105  return 0;
3106 
3107  std::size_t changes = 0;
3108 
3109  for (std::size_t i = 0; i < (g.token_list_.size() - 1); ++i)
3110  {
3111  token t;
3112 
3113  while (join(g[i], g[i + 1], t))
3114  {
3115  g.token_list_[i] = t;
3116 
3117  g.token_list_.erase(g.token_list_.begin() + static_cast<diff_t>(i + 1));
3118 
3119  ++changes;
3120  }
3121  }
3122 
3123  return changes;
3124  }
3125 
3126  inline std::size_t process_stride_3(generator& g)
3127  {
3128  typedef std::iterator_traits<generator::token_list_t::iterator>::difference_type diff_t;
3129 
3130  if (g.token_list_.size() < 3)
3131  return 0;
3132 
3133  std::size_t changes = 0;
3134 
3135  for (std::size_t i = 0; i < (g.token_list_.size() - 2); ++i)
3136  {
3137  token t;
3138 
3139  while (join(g[i], g[i + 1], g[i + 2], t))
3140  {
3141  g.token_list_[i] = t;
3142 
3143  g.token_list_.erase(g.token_list_.begin() + static_cast<diff_t>(i + 1),
3144  g.token_list_.begin() + static_cast<diff_t>(i + 3));
3145  ++changes;
3146  }
3147  }
3148 
3149  return changes;
3150  }
3151 
3152  const std::size_t stride_;
3153  };
3154 
3155  namespace helper
3156  {
3157 
3159  {
3160  for (std::size_t i = 0; i < generator.size(); ++i)
3161  {
3162  lexer::token t = generator[i];
3163  printf("Token[%02d] @ %03d %6s --> '%s'\n",
3164  static_cast<int>(i),
3165  static_cast<int>(t.position),
3166  t.to_str(t.type).c_str(),
3167  t.value.c_str());
3168  }
3169  }
3170 
3172  {
3173  public:
3174 
3176 
3178  : lexer::token_inserter(2)
3179  {}
3180 
3181  inline void ignore_symbol(const std::string& symbol)
3182  {
3183  ignore_set_.insert(symbol);
3184  }
3185 
3186  inline int insert(const lexer::token& t0, const lexer::token& t1, lexer::token& new_token)
3187  {
3188  bool match = false;
3189  new_token.type = lexer::token::e_mul;
3190  new_token.value = "*";
3191  new_token.position = t1.position;
3192 
3193  if (t0.type == lexer::token::e_symbol)
3194  {
3195  if (ignore_set_.end() != ignore_set_.find(t0.value))
3196  {
3197  return -1;
3198  }
3199  else if (!t0.value.empty() && ('$' == t0.value[0]))
3200  {
3201  return -1;
3202  }
3203  }
3204 
3205  if (t1.type == lexer::token::e_symbol)
3206  {
3207  if (ignore_set_.end() != ignore_set_.find(t1.value))
3208  {
3209  return -1;
3210  }
3211  }
3212  if ((t0.type == lexer::token::e_number ) && (t1.type == lexer::token::e_symbol )) match = true;
3213  else if ((t0.type == lexer::token::e_number ) && (t1.type == lexer::token::e_lbracket )) match = true;
3214  else if ((t0.type == lexer::token::e_number ) && (t1.type == lexer::token::e_lcrlbracket)) match = true;
3215  else if ((t0.type == lexer::token::e_number ) && (t1.type == lexer::token::e_lsqrbracket)) match = true;
3216  else if ((t0.type == lexer::token::e_symbol ) && (t1.type == lexer::token::e_number )) match = true;
3217  else if ((t0.type == lexer::token::e_rbracket ) && (t1.type == lexer::token::e_number )) match = true;
3218  else if ((t0.type == lexer::token::e_rcrlbracket) && (t1.type == lexer::token::e_number )) match = true;
3219  else if ((t0.type == lexer::token::e_rsqrbracket) && (t1.type == lexer::token::e_number )) match = true;
3220  else if ((t0.type == lexer::token::e_rbracket ) && (t1.type == lexer::token::e_symbol )) match = true;
3221  else if ((t0.type == lexer::token::e_rcrlbracket) && (t1.type == lexer::token::e_symbol )) match = true;
3222  else if ((t0.type == lexer::token::e_rsqrbracket) && (t1.type == lexer::token::e_symbol )) match = true;
3223 
3224  return (match) ? 1 : -1;
3225  }
3226 
3227  private:
3228 
3229  std::set<std::string,details::ilesscompare> ignore_set_;
3230  };
3231 
3233  {
3234  public:
3235 
3236  operator_joiner(const std::size_t& stride)
3237  : token_joiner(stride)
3238  {}
3239 
3240  inline bool join(const lexer::token& t0, const lexer::token& t1, lexer::token& t)
3241  {
3242  // ': =' --> ':='
3243  if ((t0.type == lexer::token::e_colon) && (t1.type == lexer::token::e_eq))
3244  {
3246  t.value = ":=";
3247  t.position = t0.position;
3248 
3249  return true;
3250  }
3251  // '+ =' --> '+='
3252  else if ((t0.type == lexer::token::e_add) && (t1.type == lexer::token::e_eq))
3253  {
3255  t.value = "+=";
3256  t.position = t0.position;
3257 
3258  return true;
3259  }
3260  // '- =' --> '-='
3261  else if ((t0.type == lexer::token::e_sub) && (t1.type == lexer::token::e_eq))
3262  {
3264  t.value = "-=";
3265  t.position = t0.position;
3266 
3267  return true;
3268  }
3269  // '* =' --> '*='
3270  else if ((t0.type == lexer::token::e_mul) && (t1.type == lexer::token::e_eq))
3271  {
3273  t.value = "*=";
3274  t.position = t0.position;
3275 
3276  return true;
3277  }
3278  // '/ =' --> '/='
3279  else if ((t0.type == lexer::token::e_div) && (t1.type == lexer::token::e_eq))
3280  {
3282  t.value = "/=";
3283  t.position = t0.position;
3284 
3285  return true;
3286  }
3287  // '% =' --> '%='
3288  else if ((t0.type == lexer::token::e_mod) && (t1.type == lexer::token::e_eq))
3289  {
3291  t.value = "%=";
3292  t.position = t0.position;
3293 
3294  return true;
3295  }
3296  // '> =' --> '>='
3297  else if ((t0.type == lexer::token::e_gt) && (t1.type == lexer::token::e_eq))
3298  {
3300  t.value = ">=";
3301  t.position = t0.position;
3302 
3303  return true;
3304  }
3305  // '< =' --> '<='
3306  else if ((t0.type == lexer::token::e_lt) && (t1.type == lexer::token::e_eq))
3307  {
3309  t.value = "<=";
3310  t.position = t0.position;
3311 
3312  return true;
3313  }
3314  // '= =' --> '=='
3315  else if ((t0.type == lexer::token::e_eq) && (t1.type == lexer::token::e_eq))
3316  {
3318  t.value = "==";
3319  t.position = t0.position;
3320 
3321  return true;
3322  }
3323  // '! =' --> '!='
3324  else if ((static_cast<char>(t0.type) == '!') && (t1.type == lexer::token::e_eq))
3325  {
3327  t.value = "!=";
3328  t.position = t0.position;
3329 
3330  return true;
3331  }
3332  // '< >' --> '<>'
3333  else if ((t0.type == lexer::token::e_lt) && (t1.type == lexer::token::e_gt))
3334  {
3336  t.value = "<>";
3337  t.position = t0.position;
3338 
3339  return true;
3340  }
3341  // '<= >' --> '<=>'
3342  else if ((t0.type == lexer::token::e_lte) && (t1.type == lexer::token::e_gt))
3343  {
3345  t.value = "<=>";
3346  t.position = t0.position;
3347 
3348  return true;
3349  }
3350  // '+ -' --> '-'
3351  else if ((t0.type == lexer::token::e_add) && (t1.type == lexer::token::e_sub))
3352  {
3354  t.value = "-";
3355  t.position = t0.position;
3356 
3357  return true;
3358  }
3359  // '- +' --> '-'
3360  else if ((t0.type == lexer::token::e_sub) && (t1.type == lexer::token::e_add))
3361  {
3363  t.value = "-";
3364  t.position = t0.position;
3365 
3366  return true;
3367  }
3368  // '- -' --> '+'
3369  else if ((t0.type == lexer::token::e_sub) && (t1.type == lexer::token::e_sub))
3370  {
3371  /*
3372  Note: May need to reconsider this when wanting to implement
3373  pre/postfix decrement operator
3374  */
3376  t.value = "+";
3377  t.position = t0.position;
3378 
3379  return true;
3380  }
3381  else
3382  return false;
3383  }
3384 
3385  inline bool join(const lexer::token& t0, const lexer::token& t1, const lexer::token& t2, lexer::token& t)
3386  {
3387  // '[ * ]' --> '[*]'
3388  if (
3390  (t1.type == lexer::token::e_mul ) &&
3392  )
3393  {
3395  t.value = "[*]";
3396  t.position = t0.position;
3397 
3398  return true;
3399  }
3400  else
3401  return false;
3402  }
3403  };
3404 
3406  {
3407  public:
3408 
3409  using lexer::token_scanner::operator();
3410 
3412  : token_scanner(1),
3413  state_(true)
3414  {}
3415 
3416  bool result()
3417  {
3418  if (!stack_.empty())
3419  {
3420  lexer::token t;
3421  t.value = stack_.top().first;
3422  t.position = stack_.top().second;
3423  error_token_ = t;
3424  state_ = false;
3425 
3426  return false;
3427  }
3428  else
3429  return state_;
3430  }
3431 
3433  {
3434  return error_token_;
3435  }
3436 
3437  void reset()
3438  {
3439  // Why? because msvc doesn't support swap properly.
3440  stack_ = std::stack<std::pair<char,std::size_t> >();
3441  state_ = true;
3442  error_token_.clear();
3443  }
3444 
3446  {
3447  if (
3448  !t.value.empty() &&
3449  (lexer::token::e_string != t.type) &&
3450  (lexer::token::e_symbol != t.type) &&
3452  )
3453  {
3454  details::char_t c = t.value[0];
3455 
3456  if (t.type == lexer::token::e_lbracket ) stack_.push(std::make_pair(')',t.position));
3457  else if (t.type == lexer::token::e_lcrlbracket) stack_.push(std::make_pair('}',t.position));
3458  else if (t.type == lexer::token::e_lsqrbracket) stack_.push(std::make_pair(']',t.position));
3460  {
3461  if (stack_.empty())
3462  {
3463  state_ = false;
3464  error_token_ = t;
3465 
3466  return false;
3467  }
3468  else if (c != stack_.top().first)
3469  {
3470  state_ = false;
3471  error_token_ = t;
3472 
3473  return false;
3474  }
3475  else
3476  stack_.pop();
3477  }
3478  }
3479 
3480  return true;
3481  }
3482 
3483  private:
3484 
3485  bool state_;
3486  std::stack<std::pair<char,std::size_t> > stack_;
3488  };
3489 
3491  {
3492  public:
3493 
3494  using lexer::token_scanner::operator();
3495 
3497  : token_scanner (1),
3498  current_index_(0)
3499  {}
3500 
3501  bool result()
3502  {
3503  return error_list_.empty();
3504  }
3505 
3506  void reset()
3507  {
3508  error_list_.clear();
3509  current_index_ = 0;
3510  }
3511 
3513  {
3514  if (token::e_number == t.type)
3515  {
3516  double v;
3517 
3519  {
3520  error_list_.push_back(current_index_);
3521  }
3522  }
3523 
3524  ++current_index_;
3525 
3526  return true;
3527  }
3528 
3529  std::size_t error_count() const
3530  {
3531  return error_list_.size();
3532  }
3533 
3534  std::size_t error_index(const std::size_t& i)
3535  {
3536  if (i < error_list_.size())
3537  return error_list_[i];
3538  else
3540  }
3541 
3543  {
3544  error_list_.clear();
3545  }
3546 
3547  private:
3548 
3549  std::size_t current_index_;
3550  std::vector<std::size_t> error_list_;
3551  };
3552 
3554  {
3555  private:
3556 
3557  typedef std::map<std::string,std::pair<std::string,token::token_type>,details::ilesscompare> replace_map_t;
3558 
3559  public:
3560 
3561  bool remove(const std::string& target_symbol)
3562  {
3563  const replace_map_t::iterator itr = replace_map_.find(target_symbol);
3564 
3565  if (replace_map_.end() == itr)
3566  return false;
3567 
3568  replace_map_.erase(itr);
3569 
3570  return true;
3571  }
3572 
3573  bool add_replace(const std::string& target_symbol,
3574  const std::string& replace_symbol,
3576  {
3577  const replace_map_t::iterator itr = replace_map_.find(target_symbol);
3578 
3579  if (replace_map_.end() != itr)
3580  {
3581  return false;
3582  }
3583 
3584  replace_map_[target_symbol] = std::make_pair(replace_symbol,token_type);
3585 
3586  return true;
3587  }
3588 
3589  void clear()
3590  {
3591  replace_map_.clear();
3592  }
3593 
3594  private:
3595 
3597  {
3598  if (lexer::token::e_symbol == t.type)
3599  {
3600  if (replace_map_.empty())
3601  return false;
3602 
3603  const replace_map_t::iterator itr = replace_map_.find(t.value);
3604 
3605  if (replace_map_.end() != itr)
3606  {
3607  t.value = itr->second.first;
3608  t.type = itr->second.second;
3609 
3610  return true;
3611  }
3612  }
3613 
3614  return false;
3615  }
3616 
3618  };
3619 
3621  {
3622  private:
3623 
3624  typedef std::pair<lexer::token::token_type,lexer::token::token_type> token_pair_t;
3625  typedef std::set<token_pair_t> set_t;
3626 
3627  public:
3628 
3629  using lexer::token_scanner::operator();
3630 
3632  : lexer::token_scanner(2)
3633  {
3656  }
3657 
3658  bool result()
3659  {
3660  return error_list_.empty();
3661  }
3662 
3663  bool operator() (const lexer::token& t0, const lexer::token& t1)
3664  {
3665  const set_t::value_type p = std::make_pair(t0.type,t1.type);
3666 
3667  if (invalid_bracket_check(t0.type,t1.type))
3668  {
3669  error_list_.push_back(std::make_pair(t0,t1));
3670  }
3671  else if (invalid_comb_.find(p) != invalid_comb_.end())
3672  {
3673  error_list_.push_back(std::make_pair(t0,t1));
3674  }
3675 
3676  return true;
3677  }
3678 
3679  std::size_t error_count() const
3680  {
3681  return error_list_.size();
3682  }
3683 
3684  std::pair<lexer::token,lexer::token> error(const std::size_t index)
3685  {
3686  if (index < error_list_.size())
3687  {
3688  return error_list_[index];
3689  }
3690  else
3691  {
3692  static const lexer::token error_token;
3693  return std::make_pair(error_token,error_token);
3694  }
3695  }
3696 
3698  {
3699  error_list_.clear();
3700  }
3701 
3702  private:
3703 
3705  {
3706  invalid_comb_.insert(std::make_pair(base,t));
3707  }
3708 
3710  {
3726  }
3727 
3729  {
3730  if (details::is_right_bracket(static_cast<char>(base)))
3731  {
3732  switch (t)
3733  {
3734  case lexer::token::e_assign : return (']' != base);
3735  case lexer::token::e_string : return true;
3736  default : return false;
3737  }
3738  }
3739  else if (details::is_left_bracket(static_cast<char>(base)))
3740  {
3741  if (details::is_right_bracket(static_cast<char>(t)))
3742  return false;
3743  else if (details::is_left_bracket(static_cast<char>(t)))
3744  return false;
3745  else
3746  {
3747  switch (t)
3748  {
3749  case lexer::token::e_number : return false;
3750  case lexer::token::e_symbol : return false;
3751  case lexer::token::e_string : return false;
3752  case lexer::token::e_add : return false;
3753  case lexer::token::e_sub : return false;
3754  case lexer::token::e_colon : return false;
3755  case lexer::token::e_ternary : return false;
3756  default : return true ;
3757  }
3758  }
3759  }
3760  else if (details::is_right_bracket(static_cast<char>(t)))
3761  {
3762  switch (base)
3763  {
3764  case lexer::token::e_number : return false;
3765  case lexer::token::e_symbol : return false;
3766  case lexer::token::e_string : return false;
3767  case lexer::token::e_eof : return false;
3768  case lexer::token::e_colon : return false;
3769  case lexer::token::e_ternary : return false;
3770  default : return true ;
3771  }
3772  }
3773  else if (details::is_left_bracket(static_cast<char>(t)))
3774  {
3775  switch (base)
3776  {
3777  case lexer::token::e_rbracket : return true;
3778  case lexer::token::e_rsqrbracket : return true;
3779  case lexer::token::e_rcrlbracket : return true;
3780  default : return false;
3781  }
3782  }
3783 
3784  return false;
3785  }
3786 
3788  std::vector<std::pair<lexer::token,lexer::token> > error_list_;
3789  };
3790 
3792  {
3794  {
3795  if (token_scanner_list.end() != std::find(token_scanner_list.begin(),
3796  token_scanner_list.end (),
3797  scanner))
3798  {
3799  return false;
3800  }
3801 
3802  token_scanner_list.push_back(scanner);
3803 
3804  return true;
3805  }
3806 
3808  {
3809  if (token_modifier_list.end() != std::find(token_modifier_list.begin(),
3810  token_modifier_list.end (),
3811  modifier))
3812  {
3813  return false;
3814  }
3815 
3816  token_modifier_list.push_back(modifier);
3817 
3818  return true;
3819  }
3820 
3822  {
3823  if (token_joiner_list.end() != std::find(token_joiner_list.begin(),
3824  token_joiner_list.end (),
3825  joiner))
3826  {
3827  return false;
3828  }
3829 
3830  token_joiner_list.push_back(joiner);
3831 
3832  return true;
3833  }
3834 
3836  {
3837  if (token_inserter_list.end() != std::find(token_inserter_list.begin(),
3838  token_inserter_list.end (),
3839  inserter))
3840  {
3841  return false;
3842  }
3843 
3844  token_inserter_list.push_back(inserter);
3845 
3846  return true;
3847  }
3848 
3850  {
3851  error_token_modifier = reinterpret_cast<lexer::token_modifier*>(0);
3852 
3853  for (std::size_t i = 0; i < token_modifier_list.size(); ++i)
3854  {
3855  lexer::token_modifier& modifier = (*token_modifier_list[i]);
3856 
3857  modifier.reset();
3858  modifier.process(g);
3859 
3860  if (!modifier.result())
3861  {
3863 
3864  return false;
3865  }
3866  }
3867 
3868  return true;
3869  }
3870 
3872  {
3873  error_token_joiner = reinterpret_cast<lexer::token_joiner*>(0);
3874 
3875  for (std::size_t i = 0; i < token_joiner_list.size(); ++i)
3876  {
3877  lexer::token_joiner& joiner = (*token_joiner_list[i]);
3878 
3879  joiner.reset();
3880  joiner.process(g);
3881 
3882  if (!joiner.result())
3883  {
3885 
3886  return false;
3887  }
3888  }
3889 
3890  return true;
3891  }
3892 
3894  {
3895  error_token_inserter = reinterpret_cast<lexer::token_inserter*>(0);
3896 
3897  for (std::size_t i = 0; i < token_inserter_list.size(); ++i)
3898  {
3899  lexer::token_inserter& inserter = (*token_inserter_list[i]);
3900 
3901  inserter.reset();
3902  inserter.process(g);
3903 
3904  if (!inserter.result())
3905  {
3907 
3908  return false;
3909  }
3910  }
3911 
3912  return true;
3913  }
3914 
3916  {
3917  error_token_scanner = reinterpret_cast<lexer::token_scanner*>(0);
3918 
3919  for (std::size_t i = 0; i < token_scanner_list.size(); ++i)
3920  {
3921  lexer::token_scanner& scanner = (*token_scanner_list[i]);
3922 
3923  scanner.reset();
3924  scanner.process(g);
3925 
3926  if (!scanner.result())
3927  {
3929 
3930  return false;
3931  }
3932  }
3933 
3934  return true;
3935  }
3936 
3937  std::vector<lexer::token_scanner*> token_scanner_list;
3938  std::vector<lexer::token_modifier*> token_modifier_list;
3939  std::vector<lexer::token_joiner*> token_joiner_list;
3940  std::vector<lexer::token_inserter*> token_inserter_list;
3941 
3946  };
3947  }
3948 
3950  {
3951  public:
3952 
3953  typedef token token_t;
3955 
3956  inline bool init(const std::string& str)
3957  {
3958  if (!lexer_.process(str))
3959  {
3960  return false;
3961  }
3962 
3963  lexer_.begin();
3964 
3965  next_token();
3966 
3967  return true;
3968  }
3969 
3970  inline generator_t& lexer()
3971  {
3972  return lexer_;
3973  }
3974 
3975  inline const generator_t& lexer() const
3976  {
3977  return lexer_;
3978  }
3979 
3980  inline void store_token()
3981  {
3982  lexer_.store();
3984  }
3985 
3986  inline void restore_token()
3987  {
3988  lexer_.restore();
3990  }
3991 
3992  inline void next_token()
3993  {
3995  }
3996 
3997  inline const token_t& current_token() const
3998  {
3999  return current_token_;
4000  }
4001 
4003  {
4004  e_hold = 0,
4006  };
4007 
4008  inline void advance_token(const token_advance_mode mode)
4009  {
4010  if (e_advance == mode)
4011  {
4012  next_token();
4013  }
4014  }
4015 
4016  inline bool token_is(const token_t::token_type& ttype, const token_advance_mode mode = e_advance)
4017  {
4018  if (current_token().type != ttype)
4019  {
4020  return false;
4021  }
4022 
4023  advance_token(mode);
4024 
4025  return true;
4026  }
4027 
4028  inline bool token_is(const token_t::token_type& ttype,
4029  const std::string& value,
4030  const token_advance_mode mode = e_advance)
4031  {
4032  if (
4033  (current_token().type != ttype) ||
4034  !exprtk::details::imatch(value,current_token().value)
4035  )
4036  {
4037  return false;
4038  }
4039 
4040  advance_token(mode);
4041 
4042  return true;
4043  }
4044 
4045  inline bool peek_token_is(const token_t::token_type& ttype)
4046  {
4047  return (lexer_.peek_next_token().type == ttype);
4048  }
4049 
4050  inline bool peek_token_is(const std::string& s)
4051  {
4053  }
4054 
4055  private:
4056 
4060  };
4061  }
4062 
4063  template <typename T>
4065  {
4066  public:
4067 
4068  typedef T* data_ptr_t;
4069 
4070  vector_view(data_ptr_t data, const std::size_t& size)
4071  : size_(size),
4072  data_(data),
4073  data_ref_(0)
4074  {}
4075 
4077  : size_(vv.size_),
4078  data_(vv.data_),
4079  data_ref_(0)
4080  {}
4081 
4082  inline void rebase(data_ptr_t data)
4083  {
4084  data_ = data;
4085 
4086  if (!data_ref_.empty())
4087  {
4088  for (std::size_t i = 0; i < data_ref_.size(); ++i)
4089  {
4090  (*data_ref_[i]) = data;
4091  }
4092  }
4093  }
4094 
4095  inline data_ptr_t data() const
4096  {
4097  return data_;
4098  }
4099 
4100  inline std::size_t size() const
4101  {
4102  return size_;
4103  }
4104 
4105  inline const T& operator[](const std::size_t index) const
4106  {
4107  return data_[index];
4108  }
4109 
4110  inline T& operator[](const std::size_t index)
4111  {
4112  return data_[index];
4113  }
4114 
4115  void set_ref(data_ptr_t* data_ref)
4116  {
4117  data_ref_.push_back(data_ref);
4118  }
4119 
4120  private:
4121 
4122  const std::size_t size_;
4124  std::vector<data_ptr_t*> data_ref_;
4125  };
4126 
4127  template <typename T>
4129  const std::size_t size, const std::size_t offset = 0)
4130  {
4131  return vector_view<T>(data + offset,size);
4132  }
4133 
4134  template <typename T>
4135  inline vector_view<T> make_vector_view(std::vector<T>& v,
4136  const std::size_t size, const std::size_t offset = 0)
4137  {
4138  return vector_view<T>(v.data() + offset,size);
4139  }
4140 
4141  template <typename T> class results_context;
4142 
4143  template <typename T>
4144  struct type_store
4145  {
4147  {
4152  };
4153 
4155  : size(0),
4156  data(0),
4157  type(e_unknown)
4158  {}
4159 
4160  std::size_t size;
4161  void* data;
4163 
4165  {
4166  public:
4167 
4168  parameter_list(std::vector<type_store>& pl)
4169  : parameter_list_(pl)
4170  {}
4171 
4172  inline bool empty() const
4173  {
4174  return parameter_list_.empty();
4175  }
4176 
4177  inline std::size_t size() const
4178  {
4179  return parameter_list_.size();
4180  }
4181 
4182  inline type_store& operator[](const std::size_t& index)
4183  {
4184  return parameter_list_[index];
4185  }
4186 
4187  inline const type_store& operator[](const std::size_t& index) const
4188  {
4189  return parameter_list_[index];
4190  }
4191 
4192  inline type_store& front()
4193  {
4194  return parameter_list_[0];
4195  }
4196 
4197  inline const type_store& front() const
4198  {
4199  return parameter_list_[0];
4200  }
4201 
4202  inline type_store& back()
4203  {
4204  return parameter_list_.back();
4205  }
4206 
4207  inline const type_store& back() const
4208  {
4209  return parameter_list_.back();
4210  }
4211 
4212  private:
4213 
4214  std::vector<type_store>& parameter_list_;
4215 
4216  friend class results_context<T>;
4217  };
4218 
4219  template <typename ViewType>
4220  struct type_view
4221  {
4223  typedef ViewType value_t;
4224 
4226  : ts_(ts),
4227  data_(reinterpret_cast<value_t*>(ts_.data))
4228  {}
4229 
4231  : ts_(const_cast<type_store_t&>(ts)),
4232  data_(reinterpret_cast<value_t*>(ts_.data))
4233  {}
4234 
4235  inline std::size_t size() const
4236  {
4237  return ts_.size;
4238  }
4239 
4240  inline value_t& operator[](const std::size_t& i)
4241  {
4242  return data_[i];
4243  }
4244 
4245  inline const value_t& operator[](const std::size_t& i) const
4246  {
4247  return data_[i];
4248  }
4249 
4250  inline const value_t* begin() const { return data_; }
4251  inline value_t* begin() { return data_; }
4252 
4253  inline const value_t* end() const
4254  {
4255  return static_cast<value_t*>(data_ + ts_.size);
4256  }
4257 
4258  inline value_t* end()
4259  {
4260  return static_cast<value_t*>(data_ + ts_.size);
4261  }
4262 
4265  };
4266 
4269 
4271  {
4273  typedef T value_t;
4274 
4276  : v_(*reinterpret_cast<value_t*>(ts.data))
4277  {}
4278 
4280  : v_(*reinterpret_cast<value_t*>(const_cast<type_store_t&>(ts).data))
4281  {}
4282 
4284  {
4285  return v_;
4286  }
4287 
4288  inline const value_t& operator() () const
4289  {
4290  return v_;
4291  }
4292 
4293  template <typename IntType>
4294  inline bool to_int(IntType& i) const
4295  {
4297  return false;
4298 
4299  i = static_cast<IntType>(v_);
4300 
4301  return true;
4302  }
4303 
4304  template <typename UIntType>
4305  inline bool to_uint(UIntType& u) const
4306  {
4307  if (v_ < T(0))
4308  return false;
4310  return false;
4311 
4312  u = static_cast<UIntType>(v_);
4313 
4314  return true;
4315  }
4316 
4317  T& v_;
4318  };
4319  };
4320 
4321  template <typename StringView>
4322  inline std::string to_str(const StringView& view)
4323  {
4324  return std::string(view.begin(),view.size());
4325  }
4326 
4327  #ifndef exprtk_disable_return_statement
4328  namespace details
4329  {
4330  template <typename T> class return_node;
4331  template <typename T> class return_envelope_node;
4332  }
4333  #endif
4334 
4335  template <typename T>
4336  class results_context
4337  {
4338  public:
4339 
4341 
4343  : results_available_(false)
4344  {}
4345 
4346  inline std::size_t count() const
4347  {
4348  if (results_available_)
4349  return parameter_list_.size();
4350  else
4351  return 0;
4352  }
4353 
4354  inline type_store_t& operator[](const std::size_t& index)
4355  {
4356  return parameter_list_[index];
4357  }
4358 
4359  inline const type_store_t& operator[](const std::size_t& index) const
4360  {
4361  return parameter_list_[index];
4362  }
4363 
4364  private:
4365 
4366  inline void clear()
4367  {
4368  results_available_ = false;
4369  }
4370 
4371  typedef std::vector<type_store_t> ts_list_t;
4373 
4374  inline void assign(const parameter_list_t& pl)
4375  {
4377  results_available_ = true;
4378  }
4379 
4382 
4383  #ifndef exprtk_disable_return_statement
4384  friend class details::return_node<T>;
4386  #endif
4387  };
4388 
4389  namespace details
4390  {
4392  {
4417 
4418  // Do not add new functions/operators after this point.
4419  e_sf00 = 1000, e_sf01 = 1001, e_sf02 = 1002, e_sf03 = 1003,
4420  e_sf04 = 1004, e_sf05 = 1005, e_sf06 = 1006, e_sf07 = 1007,
4421  e_sf08 = 1008, e_sf09 = 1009, e_sf10 = 1010, e_sf11 = 1011,
4422  e_sf12 = 1012, e_sf13 = 1013, e_sf14 = 1014, e_sf15 = 1015,
4423  e_sf16 = 1016, e_sf17 = 1017, e_sf18 = 1018, e_sf19 = 1019,
4424  e_sf20 = 1020, e_sf21 = 1021, e_sf22 = 1022, e_sf23 = 1023,
4425  e_sf24 = 1024, e_sf25 = 1025, e_sf26 = 1026, e_sf27 = 1027,
4426  e_sf28 = 1028, e_sf29 = 1029, e_sf30 = 1030, e_sf31 = 1031,
4427  e_sf32 = 1032, e_sf33 = 1033, e_sf34 = 1034, e_sf35 = 1035,
4428  e_sf36 = 1036, e_sf37 = 1037, e_sf38 = 1038, e_sf39 = 1039,
4429  e_sf40 = 1040, e_sf41 = 1041, e_sf42 = 1042, e_sf43 = 1043,
4430  e_sf44 = 1044, e_sf45 = 1045, e_sf46 = 1046, e_sf47 = 1047,
4431  e_sf48 = 1048, e_sf49 = 1049, e_sf50 = 1050, e_sf51 = 1051,
4432  e_sf52 = 1052, e_sf53 = 1053, e_sf54 = 1054, e_sf55 = 1055,
4433  e_sf56 = 1056, e_sf57 = 1057, e_sf58 = 1058, e_sf59 = 1059,
4434  e_sf60 = 1060, e_sf61 = 1061, e_sf62 = 1062, e_sf63 = 1063,
4435  e_sf64 = 1064, e_sf65 = 1065, e_sf66 = 1066, e_sf67 = 1067,
4436  e_sf68 = 1068, e_sf69 = 1069, e_sf70 = 1070, e_sf71 = 1071,
4437  e_sf72 = 1072, e_sf73 = 1073, e_sf74 = 1074, e_sf75 = 1075,
4438  e_sf76 = 1076, e_sf77 = 1077, e_sf78 = 1078, e_sf79 = 1079,
4439  e_sf80 = 1080, e_sf81 = 1081, e_sf82 = 1082, e_sf83 = 1083,
4440  e_sf84 = 1084, e_sf85 = 1085, e_sf86 = 1086, e_sf87 = 1087,
4441  e_sf88 = 1088, e_sf89 = 1089, e_sf90 = 1090, e_sf91 = 1091,
4442  e_sf92 = 1092, e_sf93 = 1093, e_sf94 = 1094, e_sf95 = 1095,
4443  e_sf96 = 1096, e_sf97 = 1097, e_sf98 = 1098, e_sf99 = 1099,
4444  e_sffinal = 1100,
4445  e_sf4ext00 = 2000, e_sf4ext01 = 2001, e_sf4ext02 = 2002, e_sf4ext03 = 2003,
4446  e_sf4ext04 = 2004, e_sf4ext05 = 2005, e_sf4ext06 = 2006, e_sf4ext07 = 2007,
4447  e_sf4ext08 = 2008, e_sf4ext09 = 2009, e_sf4ext10 = 2010, e_sf4ext11 = 2011,
4448  e_sf4ext12 = 2012, e_sf4ext13 = 2013, e_sf4ext14 = 2014, e_sf4ext15 = 2015,
4449  e_sf4ext16 = 2016, e_sf4ext17 = 2017, e_sf4ext18 = 2018, e_sf4ext19 = 2019,
4450  e_sf4ext20 = 2020, e_sf4ext21 = 2021, e_sf4ext22 = 2022, e_sf4ext23 = 2023,
4451  e_sf4ext24 = 2024, e_sf4ext25 = 2025, e_sf4ext26 = 2026, e_sf4ext27 = 2027,
4452  e_sf4ext28 = 2028, e_sf4ext29 = 2029, e_sf4ext30 = 2030, e_sf4ext31 = 2031,
4453  e_sf4ext32 = 2032, e_sf4ext33 = 2033, e_sf4ext34 = 2034, e_sf4ext35 = 2035,
4454  e_sf4ext36 = 2036, e_sf4ext37 = 2037, e_sf4ext38 = 2038, e_sf4ext39 = 2039,
4455  e_sf4ext40 = 2040, e_sf4ext41 = 2041, e_sf4ext42 = 2042, e_sf4ext43 = 2043,
4456  e_sf4ext44 = 2044, e_sf4ext45 = 2045, e_sf4ext46 = 2046, e_sf4ext47 = 2047,
4457  e_sf4ext48 = 2048, e_sf4ext49 = 2049, e_sf4ext50 = 2050, e_sf4ext51 = 2051,
4458  e_sf4ext52 = 2052, e_sf4ext53 = 2053, e_sf4ext54 = 2054, e_sf4ext55 = 2055,
4459  e_sf4ext56 = 2056, e_sf4ext57 = 2057, e_sf4ext58 = 2058, e_sf4ext59 = 2059,
4460  e_sf4ext60 = 2060, e_sf4ext61 = 2061
4461  };
4462 
4463  inline std::string to_str(const operator_type opr)
4464  {
4465  switch (opr)
4466  {
4467  case e_add : return "+";
4468  case e_sub : return "-";
4469  case e_mul : return "*";
4470  case e_div : return "/";
4471  case e_mod : return "%";
4472  case e_pow : return "^";
4473  case e_assign : return ":=";
4474  case e_addass : return "+=";
4475  case e_subass : return "-=";
4476  case e_mulass : return "*=";
4477  case e_divass : return "/=";
4478  case e_modass : return "%=";
4479  case e_lt : return "<";
4480  case e_lte : return "<=";
4481  case e_eq : return "==";
4482  case e_equal : return "=";
4483  case e_ne : return "!=";
4484  case e_nequal : return "<>";
4485  case e_gte : return ">=";
4486  case e_gt : return ">";
4487  default : return"N/A";
4488  }
4489  }
4490 
4492  {
4493  base_operation_t(const operator_type t, const unsigned int& np)
4494  : type(t),
4495  num_params(np)
4496  {}
4497 
4499  unsigned int num_params;
4500  };
4501 
4502  namespace loop_unroll
4503  {
4504  #ifndef exprtk_disable_superscalar_unroll
4505  const unsigned int global_loop_batch_size = 16;
4506  #else
4507  const unsigned int global_loop_batch_size = 4;
4508  #endif
4509 
4510  struct details
4511  {
4512  details(const std::size_t& vsize,
4513  const unsigned int loop_batch_size = global_loop_batch_size)
4514  : batch_size(loop_batch_size ),
4515  remainder (vsize % batch_size),
4516  upper_bound(static_cast<int>(vsize - (remainder ? loop_batch_size : 0)))
4517  {}
4518 
4519  unsigned int batch_size;
4522  };
4523  }
4524 
4525  #ifdef exprtk_enable_debugging
4526  inline void dump_ptr(const std::string& s, const void* ptr, const std::size_t size = 0)
4527  {
4528  if (size)
4529  exprtk_debug(("%s - addr: %p\n",s.c_str(),ptr));
4530  else
4531  exprtk_debug(("%s - addr: %p size: %d\n",
4532  s.c_str(),
4533  ptr,
4534  static_cast<unsigned int>(size)));
4535  }
4536  #else
4537  inline void dump_ptr(const std::string&, const void*) {}
4538  inline void dump_ptr(const std::string&, const void*, const std::size_t) {}
4539  #endif
4540 
4541  template <typename T>
4543  {
4544  public:
4545 
4547  typedef T* data_t;
4548 
4549  private:
4550 
4552  {
4554  : ref_count(1),
4555  size (0),
4556  data (0),
4557  destruct (true)
4558  {}
4559 
4560  control_block(const std::size_t& dsize)
4561  : ref_count(1 ),
4562  size (dsize),
4563  data (0 ),
4564  destruct (true )
4565  { create_data(); }
4566 
4567  control_block(const std::size_t& dsize, data_t dptr, bool dstrct = false)
4568  : ref_count(1 ),
4569  size (dsize ),
4570  data (dptr ),
4571  destruct (dstrct)
4572  {}
4573 
4575  {
4576  if (data && destruct && (0 == ref_count))
4577  {
4578  dump_ptr("~control_block() data",data);
4579  delete[] data;
4580  data = reinterpret_cast<data_t>(0);
4581  }
4582  }
4583 
4584  static inline control_block* create(const std::size_t& dsize, data_t data_ptr = data_t(0), bool dstrct = false)
4585  {
4586  if (dsize)
4587  {
4588  if (0 == data_ptr)
4589  return (new control_block(dsize));
4590  else
4591  return (new control_block(dsize, data_ptr, dstrct));
4592  }
4593  else
4594  return (new control_block);
4595  }
4596 
4597  static inline void destroy(control_block*& cntrl_blck)
4598  {
4599  if (cntrl_blck)
4600  {
4601  if (
4602  (0 != cntrl_blck->ref_count) &&
4603  (0 == --cntrl_blck->ref_count)
4604  )
4605  {
4606  delete cntrl_blck;
4607  }
4608 
4609  cntrl_blck = 0;
4610  }
4611  }
4612 
4613  std::size_t ref_count;
4614  std::size_t size;
4616  bool destruct;
4617 
4618  private:
4619 
4620  control_block(const control_block&);
4622 
4623  inline void create_data()
4624  {
4625  destruct = true;
4626  data = new T[size];
4627  std::fill_n(data,size,T(0));
4628  dump_ptr("control_block::create_data() - data",data,size);
4629  }
4630  };
4631 
4632  public:
4633 
4635  : control_block_(control_block::create(0))
4636  {}
4637 
4638  vec_data_store(const std::size_t& size)
4639  : control_block_(control_block::create(size,(data_t)(0),true))
4640  {}
4641 
4642  vec_data_store(const std::size_t& size, data_t data, bool dstrct = false)
4643  : control_block_(control_block::create(size, data, dstrct))
4644  {}
4645 
4646  vec_data_store(const type& vds)
4647  {
4650  }
4651 
4653  {
4655  }
4656 
4657  type& operator=(const type& vds)
4658  {
4659  if (this != &vds)
4660  {
4661  std::size_t final_size = min_size(control_block_, vds.control_block_);
4662 
4663  vds.control_block_->size = final_size;
4664  control_block_->size = final_size;
4665 
4666  if (control_block_->destruct || (0 == control_block_->data))
4667  {
4669 
4672  }
4673  }
4674 
4675  return (*this);
4676  }
4677 
4678  inline data_t data()
4679  {
4680  return control_block_->data;
4681  }
4682 
4683  inline data_t data() const
4684  {
4685  return control_block_->data;
4686  }
4687 
4688  inline std::size_t size()
4689  {
4690  return control_block_->size;
4691  }
4692 
4693  inline std::size_t size() const
4694  {
4695  return control_block_->size;
4696  }
4697 
4698  inline data_t& ref()
4699  {
4700  return control_block_->data;
4701  }
4702 
4703  inline void dump() const
4704  {
4705  #ifdef exprtk_enable_debugging
4706  exprtk_debug(("size: %d\taddress:%p\tdestruct:%c\n",
4707  size(),
4708  data(),
4709  (control_block_->destruct ? 'T' : 'F')));
4710 
4711  for (std::size_t i = 0; i < size(); ++i)
4712  {
4713  if (5 == i)
4714  exprtk_debug(("\n"));
4715 
4716  exprtk_debug(("%15.10f ",data()[i]));
4717  }
4718  exprtk_debug(("\n"));
4719  #endif
4720  }
4721 
4722  static inline void match_sizes(type& vds0, type& vds1)
4723  {
4724  std::size_t size = min_size(vds0.control_block_,vds1.control_block_);
4725  vds0.control_block_->size = size;
4726  vds1.control_block_->size = size;
4727  }
4728 
4729  private:
4730 
4731  static inline std::size_t min_size(control_block* cb0, control_block* cb1)
4732  {
4733  const std::size_t size0 = cb0->size;
4734  const std::size_t size1 = cb1->size;
4735 
4736  if (size0 && size1)
4737  return std::min(size0,size1);
4738  else
4739  return (size0) ? size0 : size1;
4740  }
4741 
4743  };
4744 
4745  namespace numeric
4746  {
4747  namespace details
4748  {
4749  template <typename T>
4750  inline T process_impl(const operator_type operation, const T arg)
4751  {
4752  switch (operation)
4753  {
4754  case e_abs : return numeric::abs (arg);
4755  case e_acos : return numeric::acos (arg);
4756  case e_acosh : return numeric::acosh(arg);
4757  case e_asin : return numeric::asin (arg);
4758  case e_asinh : return numeric::asinh(arg);
4759  case e_atan : return numeric::atan (arg);
4760  case e_atanh : return numeric::atanh(arg);
4761  case e_ceil : return numeric::ceil (arg);
4762  case e_cos : return numeric::cos (arg);
4763  case e_cosh : return numeric::cosh (arg);
4764  case e_exp : return numeric::exp (arg);
4765  case e_expm1 : return numeric::expm1(arg);
4766  case e_floor : return numeric::floor(arg);
4767  case e_log : return numeric::log (arg);
4768  case e_log10 : return numeric::log10(arg);
4769  case e_log2 : return numeric::log2 (arg);
4770  case e_log1p : return numeric::log1p(arg);
4771  case e_neg : return numeric::neg (arg);
4772  case e_pos : return numeric::pos (arg);
4773  case e_round : return numeric::round(arg);
4774  case e_sin : return numeric::sin (arg);
4775  case e_sinc : return numeric::sinc (arg);
4776  case e_sinh : return numeric::sinh (arg);
4777  case e_sqrt : return numeric::sqrt (arg);
4778  case e_tan : return numeric::tan (arg);
4779  case e_tanh : return numeric::tanh (arg);
4780  case e_cot : return numeric::cot (arg);
4781  case e_sec : return numeric::sec (arg);
4782  case e_csc : return numeric::csc (arg);
4783  case e_r2d : return numeric::r2d (arg);
4784  case e_d2r : return numeric::d2r (arg);
4785  case e_d2g : return numeric::d2g (arg);
4786  case e_g2d : return numeric::g2d (arg);
4787  case e_notl : return numeric::notl (arg);
4788  case e_sgn : return numeric::sgn (arg);
4789  case e_erf : return numeric::erf (arg);
4790  case e_erfc : return numeric::erfc (arg);
4791  case e_ncdf : return numeric::ncdf (arg);
4792  case e_frac : return numeric::frac (arg);
4793  case e_trunc : return numeric::trunc(arg);
4794 
4795  default : exprtk_debug(("numeric::details::process_impl<T> - Invalid unary operation.\n"));
4796  return std::numeric_limits<T>::quiet_NaN();
4797  }
4798  }
4799 
4800  template <typename T>
4801  inline T process_impl(const operator_type operation, const T arg0, const T arg1)
4802  {
4803  switch (operation)
4804  {
4805  case e_add : return (arg0 + arg1);
4806  case e_sub : return (arg0 - arg1);
4807  case e_mul : return (arg0 * arg1);
4808  case e_div : return (arg0 / arg1);
4809  case e_mod : return modulus<T>(arg0,arg1);
4810  case e_pow : return pow<T>(arg0,arg1);
4811  case e_atan2 : return atan2<T>(arg0,arg1);
4812  case e_min : return std::min<T>(arg0,arg1);
4813  case e_max : return std::max<T>(arg0,arg1);
4814  case e_logn : return logn<T>(arg0,arg1);
4815  case e_lt : return (arg0 < arg1) ? T(1) : T(0);
4816  case e_lte : return (arg0 <= arg1) ? T(1) : T(0);
4817  case e_eq : return std::equal_to<T>()(arg0,arg1) ? T(1) : T(0);
4818  case e_ne : return std::not_equal_to<T>()(arg0,arg1) ? T(1) : T(0);
4819  case e_gte : return (arg0 >= arg1) ? T(1) : T(0);
4820  case e_gt : return (arg0 > arg1) ? T(1) : T(0);
4821  case e_and : return and_opr <T>(arg0,arg1);
4822  case e_nand : return nand_opr<T>(arg0,arg1);
4823  case e_or : return or_opr <T>(arg0,arg1);
4824  case e_nor : return nor_opr <T>(arg0,arg1);
4825  case e_xor : return xor_opr <T>(arg0,arg1);
4826  case e_xnor : return xnor_opr<T>(arg0,arg1);
4827  case e_root : return root <T>(arg0,arg1);
4828  case e_roundn : return roundn <T>(arg0,arg1);
4829  case e_equal : return equal (arg0,arg1);
4830  case e_nequal : return nequal (arg0,arg1);
4831  case e_hypot : return hypot <T>(arg0,arg1);
4832  case e_shr : return shr <T>(arg0,arg1);
4833  case e_shl : return shl <T>(arg0,arg1);
4834 
4835  default : exprtk_debug(("numeric::details::process_impl<T> - Invalid binary operation.\n"));
4836  return std::numeric_limits<T>::quiet_NaN();
4837  }
4838  }
4839 
4840  template <typename T>
4841  inline T process_impl(const operator_type operation, const T arg0, const T arg1, int_type_tag)
4842  {
4843  switch (operation)
4844  {
4845  case e_add : return (arg0 + arg1);
4846  case e_sub : return (arg0 - arg1);
4847  case e_mul : return (arg0 * arg1);
4848  case e_div : return (arg0 / arg1);
4849  case e_mod : return arg0 % arg1;
4850  case e_pow : return pow<T>(arg0,arg1);
4851  case e_min : return std::min<T>(arg0,arg1);
4852  case e_max : return std::max<T>(arg0,arg1);
4853  case e_logn : return logn<T>(arg0,arg1);
4854  case e_lt : return (arg0 < arg1) ? T(1) : T(0);
4855  case e_lte : return (arg0 <= arg1) ? T(1) : T(0);
4856  case e_eq : return (arg0 == arg1) ? T(1) : T(0);
4857  case e_ne : return (arg0 != arg1) ? T(1) : T(0);
4858  case e_gte : return (arg0 >= arg1) ? T(1) : T(0);
4859  case e_gt : return (arg0 > arg1) ? T(1) : T(0);
4860  case e_and : return ((arg0 != T(0)) && (arg1 != T(0))) ? T(1) : T(0);
4861  case e_nand : return ((arg0 != T(0)) && (arg1 != T(0))) ? T(0) : T(1);
4862  case e_or : return ((arg0 != T(0)) || (arg1 != T(0))) ? T(1) : T(0);
4863  case e_nor : return ((arg0 != T(0)) || (arg1 != T(0))) ? T(0) : T(1);
4864  case e_xor : return arg0 ^ arg1;
4865  case e_xnor : return !(arg0 ^ arg1);
4866  case e_root : return root<T>(arg0,arg1);
4867  case e_equal : return arg0 == arg1;
4868  case e_nequal : return arg0 != arg1;
4869  case e_hypot : return hypot<T>(arg0,arg1);
4870  case e_shr : return arg0 >> arg1;
4871  case e_shl : return arg0 << arg1;
4872 
4873  default : exprtk_debug(("numeric::details::process_impl<IntType> - Invalid binary operation.\n"));
4874  return std::numeric_limits<T>::quiet_NaN();
4875  }
4876  }
4877  }
4878 
4879  template <typename T>
4880  inline T process(const operator_type operation, const T arg)
4881  {
4883  }
4884 
4885  template <typename T>
4886  inline T process(const operator_type operation, const T arg0, const T arg1)
4887  {
4888  return exprtk::details::numeric::details::process_impl(operation,arg0,arg1);
4889  }
4890  }
4891 
4892  template <typename T>
4894  {
4895  public:
4896 
4898  {
4936  };
4937 
4938  typedef T value_type;
4940 
4942  {}
4943 
4944  inline virtual T value() const
4945  {
4946  return std::numeric_limits<T>::quiet_NaN();
4947  }
4948 
4949  inline virtual expression_node<T>* branch(const std::size_t& index = 0) const
4950  {
4951  return reinterpret_cast<expression_ptr>(index * 0);
4952  }
4953 
4954  inline virtual node_type type() const
4955  {
4956  return e_none;
4957  }
4958  };
4959 
4960  template <typename T>
4961  inline bool is_generally_string_node(const expression_node<T>* node);
4962 
4963  inline bool is_true(const double v)
4964  {
4965  return std::not_equal_to<double>()(0.0,v);
4966  }
4967 
4968  inline bool is_true(const long double v)
4969  {
4970  return std::not_equal_to<long double>()(0.0L,v);
4971  }
4972 
4973  inline bool is_true(const float v)
4974  {
4975  return std::not_equal_to<float>()(0.0f,v);
4976  }
4977 
4978  template <typename T>
4979  inline bool is_true(const std::complex<T>& v)
4980  {
4981  return std::not_equal_to<std::complex<T> >()(std::complex<T>(0),v);
4982  }
4983 
4984  template <typename T>
4985  inline bool is_true(const expression_node<T>* node)
4986  {
4987  return std::not_equal_to<T>()(T(0),node->value());
4988  }
4989 
4990  template <typename T>
4991  inline bool is_false(const expression_node<T>* node)
4992  {
4993  return std::equal_to<T>()(T(0),node->value());
4994  }
4995 
4996  template <typename T>
4997  inline bool is_unary_node(const expression_node<T>* node)
4998  {
4999  return node && (details::expression_node<T>::e_unary == node->type());
5000  }
5001 
5002  template <typename T>
5003  inline bool is_neg_unary_node(const expression_node<T>* node)
5004  {
5005  return node && (details::expression_node<T>::e_neg == node->type());
5006  }
5007 
5008  template <typename T>
5009  inline bool is_binary_node(const expression_node<T>* node)
5010  {
5011  return node && (details::expression_node<T>::e_binary == node->type());
5012  }
5013 
5014  template <typename T>
5015  inline bool is_variable_node(const expression_node<T>* node)
5016  {
5017  return node && (details::expression_node<T>::e_variable == node->type());
5018  }
5019 
5020  template <typename T>
5021  inline bool is_ivariable_node(const expression_node<T>* node)
5022  {
5023  return node &&
5024  (
5029  );
5030  }
5031 
5032  template <typename T>
5033  inline bool is_vector_elem_node(const expression_node<T>* node)
5034  {
5035  return node && (details::expression_node<T>::e_vecelem == node->type());
5036  }
5037 
5038  template <typename T>
5040  {
5041  return node && (details::expression_node<T>::e_rbvecelem == node->type());
5042  }
5043 
5044  template <typename T>
5046  {
5047  return node && (details::expression_node<T>::e_rbveccelem == node->type());
5048  }
5049 
5050  template <typename T>
5051  inline bool is_vector_node(const expression_node<T>* node)
5052  {
5053  return node && (details::expression_node<T>::e_vector == node->type());
5054  }
5055 
5056  template <typename T>
5057  inline bool is_ivector_node(const expression_node<T>* node)
5058  {
5059  if (node)
5060  {
5061  switch (node->type())
5062  {
5072  case details::expression_node<T>::e_vecunaryop : return true;
5073  default : return false;
5074  }
5075  }
5076  else
5077  return false;
5078  }
5079 
5080  template <typename T>
5081  inline bool is_constant_node(const expression_node<T>* node)
5082  {
5083  return node && (details::expression_node<T>::e_constant == node->type());
5084  }
5085 
5086  template <typename T>
5087  inline bool is_null_node(const expression_node<T>* node)
5088  {
5089  return node && (details::expression_node<T>::e_null == node->type());
5090  }
5091 
5092  template <typename T>
5093  inline bool is_break_node(const expression_node<T>* node)
5094  {
5095  return node && (details::expression_node<T>::e_break == node->type());
5096  }
5097 
5098  template <typename T>
5099  inline bool is_continue_node(const expression_node<T>* node)
5100  {
5101  return node && (details::expression_node<T>::e_continue == node->type());
5102  }
5103 
5104  template <typename T>
5105  inline bool is_swap_node(const expression_node<T>* node)
5106  {
5107  return node && (details::expression_node<T>::e_swap == node->type());
5108  }
5109 
5110  template <typename T>
5111  inline bool is_function(const expression_node<T>* node)
5112  {
5113  return node && (details::expression_node<T>::e_function == node->type());
5114  }
5115 
5116  template <typename T>
5117  inline bool is_return_node(const expression_node<T>* node)
5118  {
5119  return node && (details::expression_node<T>::e_return == node->type());
5120  }
5121 
5122  template <typename T> class unary_node;
5123 
5124  template <typename T>
5125  inline bool is_negate_node(const expression_node<T>* node)
5126  {
5127  if (node && is_unary_node(node))
5128  {
5129  return (details::e_neg == static_cast<const unary_node<T>*>(node)->operation());
5130  }
5131  else
5132  return false;
5133  }
5134 
5135  template <typename T>
5137  {
5138  return !is_variable_node(node) &&
5139  !is_string_node (node) ;
5140  }
5141 
5142  template <std::size_t N, typename T>
5143  inline bool all_nodes_valid(expression_node<T>* (&b)[N])
5144  {
5145  for (std::size_t i = 0; i < N; ++i)
5146  {
5147  if (0 == b[i]) return false;
5148  }
5149 
5150  return true;
5151  }
5152 
5153  template <typename T,
5154  typename Allocator,
5155  template <typename,typename> class Sequence>
5156  inline bool all_nodes_valid(const Sequence<expression_node<T>*,Allocator>& b)
5157  {
5158  for (std::size_t i = 0; i < b.size(); ++i)
5159  {
5160  if (0 == b[i]) return false;
5161  }
5162 
5163  return true;
5164  }
5165 
5166  template <std::size_t N, typename T>
5168  {
5169  for (std::size_t i = 0; i < N; ++i)
5170  {
5171  if (0 == b[i])
5172  return false;
5173  else if (!is_variable_node(b[i]))
5174  return false;
5175  }
5176 
5177  return true;
5178  }
5179 
5180  template <typename T,
5181  typename Allocator,
5182  template <typename,typename> class Sequence>
5183  inline bool all_nodes_variables(Sequence<expression_node<T>*,Allocator>& b)
5184  {
5185  for (std::size_t i = 0; i < b.size(); ++i)
5186  {
5187  if (0 == b[i])
5188  return false;
5189  else if (!is_variable_node(b[i]))
5190  return false;
5191  }
5192 
5193  return true;
5194  }
5195 
5196  template <typename NodeAllocator, typename T, std::size_t N>
5197  inline void free_all_nodes(NodeAllocator& node_allocator, expression_node<T>* (&b)[N])
5198  {
5199  for (std::size_t i = 0; i < N; ++i)
5200  {
5201  free_node(node_allocator,b[i]);
5202  }
5203  }
5204 
5205  template <typename NodeAllocator,
5206  typename T,
5207  typename Allocator,
5208  template <typename,typename> class Sequence>
5209  inline void free_all_nodes(NodeAllocator& node_allocator, Sequence<expression_node<T>*,Allocator>& b)
5210  {
5211  for (std::size_t i = 0; i < b.size(); ++i)
5212  {
5213  free_node(node_allocator,b[i]);
5214  }
5215 
5216  b.clear();
5217  }
5218 
5219  template <typename NodeAllocator, typename T>
5220  inline void free_node(NodeAllocator& node_allocator, expression_node<T>*& node, const bool force_delete = false)
5221  {
5222  if (0 != node)
5223  {
5224  if (
5225  (is_variable_node(node) || is_string_node(node)) ||
5226  force_delete
5227  )
5228  return;
5229 
5230  node_allocator.free(node);
5231  node = reinterpret_cast<expression_node<T>*>(0);
5232  }
5233  }
5234 
5235  template <typename T>
5236  inline void destroy_node(expression_node<T>*& node)
5237  {
5238  delete node;
5239  node = reinterpret_cast<expression_node<T>*>(0);
5240  }
5241 
5242  template <typename Type>
5244  {
5245  private:
5246 
5247  typedef Type value_type;
5250 
5252  {
5253  public:
5254 
5255  virtual ~vector_holder_base() {}
5256 
5257  inline value_ptr operator[](const std::size_t& index) const
5258  {
5259  return value_at(index);
5260  }
5261 
5262  inline std::size_t size() const
5263  {
5264  return vector_size();
5265  }
5266 
5267  inline value_ptr data() const
5268  {
5269  return value_at(0);
5270  }
5271 
5272  virtual inline bool rebaseable() const
5273  {
5274  return false;
5275  }
5276 
5277  virtual void set_ref(value_ptr*) {}
5278 
5279  protected:
5280 
5281  virtual value_ptr value_at(const std::size_t&) const = 0;
5282  virtual std::size_t vector_size() const = 0;
5283  };
5284 
5286  {
5287  public:
5288 
5289  array_vector_impl(const Type* vec, const std::size_t& vec_size)
5290  : vec_(vec),
5291  size_(vec_size)
5292  {}
5293 
5294  protected:
5295 
5296  value_ptr value_at(const std::size_t& index) const
5297  {
5298  if (index < size_)
5299  return const_cast<const_value_ptr>(vec_ + index);
5300  else
5301  return const_value_ptr(0);
5302  }
5303 
5304  std::size_t vector_size() const
5305  {
5306  return size_;
5307  }
5308 
5309  private:
5310 
5312 
5313  const Type* vec_;
5314  const std::size_t size_;
5315  };
5316 
5317  template <typename Allocator,
5318  template <typename,typename> class Sequence>
5320  {
5321  public:
5322 
5323  typedef Sequence<Type,Allocator> sequence_t;
5324 
5326  : sequence_(seq)
5327  {}
5328 
5329  protected:
5330 
5331  value_ptr value_at(const std::size_t& index) const
5332  {
5333  return (index < sequence_.size()) ? (&sequence_[index]) : const_value_ptr(0);
5334  }
5335 
5336  std::size_t vector_size() const
5337  {
5338  return sequence_.size();
5339  }
5340 
5341  private:
5342 
5344 
5346  };
5347 
5349  {
5350  public:
5351 
5353 
5355  : vec_view_(vec_view)
5356  {}
5357 
5358  void set_ref(value_ptr* ref)
5359  {
5360  vec_view_.set_ref(ref);
5361  }
5362 
5363  virtual inline bool rebaseable() const
5364  {
5365  return true;
5366  }
5367 
5368  protected:
5369 
5370  value_ptr value_at(const std::size_t& index) const
5371  {
5372  return (index < vec_view_.size()) ? (&vec_view_[index]) : const_value_ptr(0);
5373  }
5374 
5375  std::size_t vector_size() const
5376  {
5377  return vec_view_.size();
5378  }
5379 
5380  private:
5381 
5383 
5385  };
5386 
5387  public:
5388 
5390 
5391  vector_holder(Type* vec, const std::size_t& vec_size)
5392  : vector_holder_base_(new(buffer)array_vector_impl(vec,vec_size))
5393  {}
5394 
5395  vector_holder(const vds_t& vds)
5396  : vector_holder_base_(new(buffer)array_vector_impl(vds.data(),vds.size()))
5397  {}
5398 
5399  template <typename Allocator>
5400  vector_holder(std::vector<Type,Allocator>& vec)
5401  : vector_holder_base_(new(buffer)sequence_vector_impl<Allocator,std::vector>(vec))
5402  {}
5403 
5405  : vector_holder_base_(new(buffer)vector_view_impl(vec))
5406  {}
5407 
5408  inline value_ptr operator[](const std::size_t& index) const
5409  {
5410  return (*vector_holder_base_)[index];
5411  }
5412 
5413  inline std::size_t size() const
5414  {
5415  return vector_holder_base_->size();
5416  }
5417 
5418  inline value_ptr data() const
5419  {
5420  return vector_holder_base_->data();
5421  }
5422 
5423  void set_ref(value_ptr* ref)
5424  {
5426  }
5427 
5428  bool rebaseable() const
5429  {
5430  return vector_holder_base_->rebaseable();
5431  }
5432 
5433  private:
5434 
5435  mutable vector_holder_base* vector_holder_base_;
5437  };
5438 
5439  template <typename T>
5440  class null_node : public expression_node<T>
5441  {
5442  public:
5443 
5444  inline T value() const
5445  {
5446  return std::numeric_limits<T>::quiet_NaN();
5447  }
5448 
5449  inline typename expression_node<T>::node_type type() const
5450  {
5452  }
5453  };
5454 
5455  template <typename T>
5456  class null_eq_node : public expression_node<T>
5457  {
5458  public:
5459 
5461 
5462  null_eq_node(expression_ptr brnch, const bool equality = true)
5463  : branch_(brnch),
5465  equality_(equality)
5466  {}
5467 
5469  {
5470  if (branch_ && branch_deletable_)
5471  {
5473  }
5474  }
5475 
5476  inline T value() const
5477  {
5478  const T v = branch_->value();
5479  const bool result = details::numeric::is_nan(v);
5480 
5481  if (result)
5482  return (equality_) ? T(1) : T(0);
5483  else
5484  return (equality_) ? T(0) : T(1);
5485  }
5486 
5487  inline typename expression_node<T>::node_type type() const
5488  {
5490  }
5491 
5492  inline operator_type operation() const
5493  {
5494  return details::e_eq;
5495  }
5496 
5497  inline expression_node<T>* branch(const std::size_t&) const
5498  {
5499  return branch_;
5500  }
5501 
5502  private:
5503 
5505  const bool branch_deletable_;
5507  };
5508 
5509  template <typename T>
5510  class literal_node : public expression_node<T>
5511  {
5512  public:
5513 
5514  explicit literal_node(const T& v)
5515  : value_(v)
5516  {}
5517 
5518  inline T value() const
5519  {
5520  return value_;
5521  }
5522 
5523  inline typename expression_node<T>::node_type type() const
5524  {
5526  }
5527 
5528  inline expression_node<T>* branch(const std::size_t&) const
5529  {
5530  return reinterpret_cast<expression_node<T>*>(0);
5531  }
5532 
5533  private:
5534 
5537 
5538  const T value_;
5539  };
5540 
5541  template <typename T>
5542  struct range_pack;
5543 
5544  template <typename T>
5546 
5547  template <typename T>
5549  {
5550  public:
5551 
5553 
5555  {}
5556 
5557  virtual range_t& range_ref() = 0;
5558 
5559  virtual const range_t& range_ref() const = 0;
5560  };
5561 
5562  #ifndef exprtk_disable_string_capabilities
5563  template <typename T>
5565  {
5566  public:
5567 
5569 
5571  {}
5572 
5573  virtual std::string str () const = 0;
5574 
5575  virtual char_cptr base() const = 0;
5576 
5577  virtual std::size_t size() const = 0;
5578  };
5579 
5580  template <typename T>
5582  public string_base_node<T>,
5583  public range_interface <T>
5584  {
5585  public:
5586 
5588 
5589  explicit string_literal_node(const std::string& v)
5590  : value_(v)
5591  {
5592  rp_.n0_c = std::make_pair<bool,std::size_t>(true,0);
5593  rp_.n1_c = std::make_pair<bool,std::size_t>(true,v.size() - 1);
5594  rp_.cache.first = rp_.n0_c.second;
5595  rp_.cache.second = rp_.n1_c.second;
5596  }
5597 
5598  inline T value() const
5599  {
5600  return std::numeric_limits<T>::quiet_NaN();
5601  }
5602 
5603  inline typename expression_node<T>::node_type type() const
5604  {
5606  }
5607 
5608  inline expression_node<T>* branch(const std::size_t&) const
5609  {
5610  return reinterpret_cast<expression_node<T>*>(0);
5611  }
5612 
5613  std::string str() const
5614  {
5615  return value_;
5616  }
5617 
5618  char_cptr base() const
5619  {
5620  return value_.data();
5621  }
5622 
5623  std::size_t size() const
5624  {
5625  return value_.size();
5626  }
5627 
5629  {
5630  return rp_;
5631  }
5632 
5633  const range_t& range_ref() const
5634  {
5635  return rp_;
5636  }
5637 
5638  private:
5639 
5642 
5643  const std::string value_;
5645  };
5646  #endif
5647 
5648  template <typename T>
5649  class unary_node : public expression_node<T>
5650  {
5651  public:
5652 
5654 
5656  expression_ptr brnch)
5657  : operation_(opr),
5658  branch_(brnch),
5660  {}
5661 
5663  {
5664  if (branch_ && branch_deletable_)
5665  {
5667  }
5668  }
5669 
5670  inline T value() const
5671  {
5672  const T arg = branch_->value();
5673 
5674  return numeric::process<T>(operation_,arg);
5675  }
5676 
5677  inline typename expression_node<T>::node_type type() const
5678  {
5680  }
5681 
5682  inline operator_type operation() const
5683  {
5684  return operation_;
5685  }
5686 
5687  inline expression_node<T>* branch(const std::size_t&) const
5688  {
5689  return branch_;
5690  }
5691 
5692  inline void release()
5693  {
5694  branch_deletable_ = false;
5695  }
5696 
5697  protected:
5698 
5702  };
5703 
5704  template <typename T, std::size_t D, bool B>
5706  {
5707  template <std::size_t N>
5708  static inline void process(std::pair<expression_node<T>*,bool> (&)[N], expression_node<T>*)
5709  {}
5710  };
5711 
5712  template <typename T, std::size_t D>
5713  struct construct_branch_pair<T,D,true>
5714  {
5715  template <std::size_t N>
5716  static inline void process(std::pair<expression_node<T>*,bool> (&branch)[N], expression_node<T>* b)
5717  {
5718  if (b)
5719  {
5720  branch[D] = std::make_pair(b,branch_deletable(b));
5721  }
5722  }
5723  };
5724 
5725  template <std::size_t N, typename T>
5726  inline void init_branches(std::pair<expression_node<T>*,bool> (&branch)[N],
5727  expression_node<T>* b0,
5728  expression_node<T>* b1 = reinterpret_cast<expression_node<T>*>(0),
5729  expression_node<T>* b2 = reinterpret_cast<expression_node<T>*>(0),
5730  expression_node<T>* b3 = reinterpret_cast<expression_node<T>*>(0),
5731  expression_node<T>* b4 = reinterpret_cast<expression_node<T>*>(0),
5732  expression_node<T>* b5 = reinterpret_cast<expression_node<T>*>(0),
5733  expression_node<T>* b6 = reinterpret_cast<expression_node<T>*>(0),
5734  expression_node<T>* b7 = reinterpret_cast<expression_node<T>*>(0),
5735  expression_node<T>* b8 = reinterpret_cast<expression_node<T>*>(0),
5736  expression_node<T>* b9 = reinterpret_cast<expression_node<T>*>(0))
5737  {
5738  construct_branch_pair<T,0,(N > 0)>::process(branch,b0);
5739  construct_branch_pair<T,1,(N > 1)>::process(branch,b1);
5740  construct_branch_pair<T,2,(N > 2)>::process(branch,b2);
5741  construct_branch_pair<T,3,(N > 3)>::process(branch,b3);
5742  construct_branch_pair<T,4,(N > 4)>::process(branch,b4);
5743  construct_branch_pair<T,5,(N > 5)>::process(branch,b5);
5744  construct_branch_pair<T,6,(N > 6)>::process(branch,b6);
5745  construct_branch_pair<T,7,(N > 7)>::process(branch,b7);
5746  construct_branch_pair<T,8,(N > 8)>::process(branch,b8);
5747  construct_branch_pair<T,9,(N > 9)>::process(branch,b9);
5748  }
5749 
5751  {
5752  template <typename T, std::size_t N>
5753  static inline void execute(std::pair<expression_node<T>*,bool> (&branch)[N])
5754  {
5755  for (std::size_t i = 0; i < N; ++i)
5756  {
5757  if (branch[i].first && branch[i].second)
5758  {
5759  destroy_node(branch[i].first);
5760  }
5761  }
5762  }
5763 
5764  template <typename T,
5765  typename Allocator,
5766  template <typename,typename> class Sequence>
5767  static inline void execute(Sequence<std::pair<expression_node<T>*,bool>,Allocator>& branch)
5768  {
5769  for (std::size_t i = 0; i < branch.size(); ++i)
5770  {
5771  if (branch[i].first && branch[i].second)
5772  {
5773  destroy_node(branch[i].first);
5774  }
5775  }
5776  }
5777  };
5778 
5779  template <typename T>
5780  class binary_node : public expression_node<T>
5781  {
5782  public:
5783 
5785  typedef std::pair<expression_ptr,bool> branch_t;
5786 
5788  expression_ptr branch0,
5789  expression_ptr branch1)
5790  : operation_(opr)
5791  {
5792  init_branches<2>(branch_, branch0, branch1);
5793  }
5794 
5796  {
5797  cleanup_branches::execute<T,2>(branch_);
5798  }
5799 
5800  inline T value() const
5801  {
5802  const T arg0 = branch_[0].first->value();
5803  const T arg1 = branch_[1].first->value();
5804 
5805  return numeric::process<T>(operation_,arg0,arg1);
5806  }
5807 
5808  inline typename expression_node<T>::node_type type() const
5809  {
5811  }
5812 
5814  {
5815  return operation_;
5816  }
5817 
5818  inline expression_node<T>* branch(const std::size_t& index = 0) const
5819  {
5820  if (0 == index)
5821  return branch_[0].first;
5822  else if (1 == index)
5823  return branch_[1].first;
5824  else
5825  return reinterpret_cast<expression_ptr>(0);
5826  }
5827 
5828  protected:
5829 
5832  };
5833 
5834  template <typename T, typename Operation>
5836  {
5837  public:
5838 
5840  typedef std::pair<expression_ptr,bool> branch_t;
5841 
5843  {
5844  init_branches<2>(branch_, branch0, branch1);
5845  }
5846 
5848  {
5849  cleanup_branches::execute<T,2>(branch_);
5850  }
5851 
5852  inline T value() const
5853  {
5854  const T arg0 = branch_[0].first->value();
5855  const T arg1 = branch_[1].first->value();
5856 
5857  return Operation::process(arg0,arg1);
5858  }
5859 
5860  inline typename expression_node<T>::node_type type() const
5861  {
5863  }
5864 
5866  {
5867  return Operation::operation();
5868  }
5869 
5870  inline expression_node<T>* branch(const std::size_t& index = 0) const
5871  {
5872  if (0 == index)
5873  return branch_[0].first;
5874  else if (1 == index)
5875  return branch_[1].first;
5876  else
5877  return reinterpret_cast<expression_ptr>(0);
5878  }
5879 
5880  protected:
5881 
5883  };
5884 
5885  template <typename T>
5886  class trinary_node : public expression_node<T>
5887  {
5888  public:
5889 
5891  typedef std::pair<expression_ptr,bool> branch_t;
5892 
5894  expression_ptr branch0,
5895  expression_ptr branch1,
5896  expression_ptr branch2)
5897  : operation_(opr)
5898  {
5899  init_branches<3>(branch_, branch0, branch1, branch2);
5900  }
5901 
5903  {
5904  cleanup_branches::execute<T,3>(branch_);
5905  }
5906 
5907  inline T value() const
5908  {
5909  const T arg0 = branch_[0].first->value();
5910  const T arg1 = branch_[1].first->value();
5911  const T arg2 = branch_[2].first->value();
5912 
5913  switch (operation_)
5914  {
5915  case e_inrange : return (arg1 < arg0) ? T(0) : ((arg1 > arg2) ? T(0) : T(1));
5916 
5917  case e_clamp : return (arg1 < arg0) ? arg0 : (arg1 > arg2 ? arg2 : arg1);
5918 
5919  case e_iclamp : if ((arg1 <= arg0) || (arg1 >= arg2))
5920  return arg1;
5921  else
5922  return ((T(2) * arg1 <= (arg2 + arg0)) ? arg0 : arg2);
5923 
5924  default : exprtk_debug(("trinary_node::value() - Error: Invalid operation\n"));
5925  return std::numeric_limits<T>::quiet_NaN();
5926  }
5927  }
5928 
5929  inline typename expression_node<T>::node_type type() const
5930  {
5932  }
5933 
5934  protected:
5935 
5938  };
5939 
5940  template <typename T>
5942  {
5943  public:
5944 
5946  typedef std::pair<expression_ptr,bool> branch_t;
5947 
5949  expression_ptr branch0,
5950  expression_ptr branch1,
5951  expression_ptr branch2,
5952  expression_ptr branch3)
5953  : operation_(opr)
5954  {
5955  init_branches<4>(branch_, branch0, branch1, branch2, branch3);
5956  }
5957 
5959  {
5960  cleanup_branches::execute<T,4>(branch_);
5961  }
5962 
5963  inline T value() const
5964  {
5965  return std::numeric_limits<T>::quiet_NaN();
5966  }
5967 
5968  inline typename expression_node<T>::node_type type() const
5969  {
5971  }
5972 
5973  protected:
5974 
5977  };
5978 
5979  template <typename T>
5981  {
5982  public:
5983 
5985 
5987  expression_ptr consequent,
5988  expression_ptr alternative)
5989  : test_(test),
5990  consequent_(consequent),
5991  alternative_(alternative),
5995  {}
5996 
5998  {
5999  if (test_ && test_deletable_)
6000  {
6002  }
6003 
6005  {
6007  }
6008 
6010  {
6012  }
6013  }
6014 
6015  inline T value() const
6016  {
6017  if (is_true(test_))
6018  return consequent_->value();
6019  else
6020  return alternative_->value();
6021  }
6022 
6023  inline typename expression_node<T>::node_type type() const
6024  {
6026  }
6027 
6028  private:
6029 
6033  const bool test_deletable_;
6036  };
6037 
6038  template <typename T>
6040  {
6041  public:
6042 
6043  // Consequent only conditional statement node
6045 
6047  expression_ptr consequent)
6048  : test_(test),
6049  consequent_(consequent),
6052  {}
6053 
6055  {
6056  if (test_ && test_deletable_)
6057  {
6059  }
6060 
6062  {
6064  }
6065  }
6066 
6067  inline T value() const
6068  {
6069  if (is_true(test_))
6070  return consequent_->value();
6071  else
6072  return std::numeric_limits<T>::quiet_NaN();
6073  }
6074 
6075  inline typename expression_node<T>::node_type type() const
6076  {
6078  }
6079 
6080  private:
6081 
6084  const bool test_deletable_;
6086  };
6087 
6088  #ifndef exprtk_disable_break_continue
6089  template <typename T>
6091  {
6092  public:
6093 
6094  break_exception(const T& v)
6095  : value(v)
6096  {}
6097 
6099  };
6100 
6102  {};
6103 
6104  template <typename T>
6105  class break_node : public expression_node<T>
6106  {
6107  public:
6108 
6110 
6112  : return_(ret),
6114  {}
6115 
6117  {
6118  if (return_deletable_)
6119  {
6121  }
6122  }
6123 
6124  inline T value() const
6125  {
6126  throw break_exception<T>(return_ ? return_->value() : std::numeric_limits<T>::quiet_NaN());
6127  #ifndef _MSC_VER
6128  return std::numeric_limits<T>::quiet_NaN();
6129  #endif
6130  }
6131 
6132  inline typename expression_node<T>::node_type type() const
6133  {
6135  }
6136 
6137  private:
6138 
6140  const bool return_deletable_;
6141  };
6142 
6143  template <typename T>
6144  class continue_node : public expression_node<T>
6145  {
6146  public:
6147 
6148  inline T value() const
6149  {
6150  throw continue_exception();
6151  #ifndef _MSC_VER
6152  return std::numeric_limits<T>::quiet_NaN();
6153  #endif
6154  }
6155 
6156  inline typename expression_node<T>::node_type type() const
6157  {
6159  }
6160  };
6161  #endif
6162 
6163  template <typename T>
6165  {
6166  public:
6167 
6169 
6171  : condition_(condition),
6172  loop_body_(loop_body),
6175  {}
6176 
6178  {
6180  {
6182  }
6183 
6185  {
6187  }
6188  }
6189 
6190  inline T value() const
6191  {
6192  T result = T(0);
6193 
6194  while (is_true(condition_))
6195  {
6196  result = loop_body_->value();
6197  }
6198 
6199  return result;
6200  }
6201 
6202  inline typename expression_node<T>::node_type type() const
6203  {
6205  }
6206 
6207  private:
6208 
6213  };
6214 
6215  template <typename T>
6217  {
6218  public:
6219 
6221 
6223  : condition_(condition),
6224  loop_body_(loop_body),
6227  {}
6228 
6230  {
6232  {
6234  }
6235 
6237  {
6239  }
6240  }
6241 
6242  inline T value() const
6243  {
6244  T result = T(0);
6245 
6246  do
6247  {
6248  result = loop_body_->value();
6249  }
6250  while (is_false(condition_));
6251 
6252  return result;
6253  }
6254 
6255  inline typename expression_node<T>::node_type type() const
6256  {
6258  }
6259 
6260  private:
6261 
6266  };
6267 
6268  template <typename T>
6269  class for_loop_node : public expression_node<T>
6270  {
6271  public:
6272 
6274 
6276  expression_ptr condition,
6277  expression_ptr incrementor,
6278  expression_ptr loop_body)
6279  : initialiser_(initialiser),
6280  condition_ (condition ),
6281  incrementor_(incrementor),
6282  loop_body_ (loop_body ),
6287  {}
6288 
6290  {
6292  {
6294  }
6295 
6297  {
6299  }
6300 
6302  {
6304  }
6305 
6307  {
6309  }
6310  }
6311 
6312  inline T value() const
6313  {
6314  T result = T(0);
6315 
6316  if (initialiser_)
6317  initialiser_->value();
6318 
6319  if (incrementor_)
6320  {
6321  while (is_true(condition_))
6322  {
6323  result = loop_body_->value();
6324  incrementor_->value();
6325  }
6326  }
6327  else
6328  {
6329  while (is_true(condition_))
6330  {
6331  result = loop_body_->value();
6332  }
6333  }
6334 
6335  return result;
6336  }
6337 
6338  inline typename expression_node<T>::node_type type() const
6339  {
6341  }
6342 
6343  private:
6344 
6353  };
6354 
6355  #ifndef exprtk_disable_break_continue
6356  template <typename T>
6358  {
6359  public:
6360 
6362 
6364  : condition_(condition),
6365  loop_body_(loop_body),
6368  {}
6369 
6371  {
6373  {
6375  }
6376 
6378  {
6380  }
6381  }
6382 
6383  inline T value() const
6384  {
6385  T result = T(0);
6386 
6387  while (is_true(condition_))
6388  {
6389  try
6390  {
6391  result = loop_body_->value();
6392  }
6393  catch(const break_exception<T>& e)
6394  {
6395  return e.value;
6396  }
6397  catch(const continue_exception&)
6398  {}
6399  }
6400 
6401  return result;
6402  }
6403 
6404  inline typename expression_node<T>::node_type type() const
6405  {
6407  }
6408 
6409  private:
6410 
6415  };
6416 
6417  template <typename T>
6419  {
6420  public:
6421 
6423 
6425  : condition_(condition),
6426  loop_body_(loop_body),
6429  {}
6430 
6432  {
6434  {
6436  }
6437 
6439  {
6441  }
6442  }
6443 
6444  inline T value() const
6445  {
6446  T result = T(0);
6447 
6448  do
6449  {
6450  try
6451  {
6452  result = loop_body_->value();
6453  }
6454  catch(const break_exception<T>& e)
6455  {
6456  return e.value;
6457  }
6458  catch(const continue_exception&)
6459  {}
6460  }
6461  while (is_false(condition_));
6462 
6463  return result;
6464  }
6465 
6466  inline typename expression_node<T>::node_type type() const
6467  {
6469  }
6470 
6471  private:
6472 
6477  };
6478 
6479  template <typename T>
6481  {
6482  public:
6483 
6485 
6487  expression_ptr condition,
6488  expression_ptr incrementor,
6489  expression_ptr loop_body)
6490  : initialiser_(initialiser),
6491  condition_ (condition ),
6492  incrementor_(incrementor),
6493  loop_body_ (loop_body ),
6498  {}
6499 
6501  {
6503  {
6505  }
6506 
6508  {
6510  }
6511 
6513  {
6515  }
6516 
6518  {
6520  }
6521  }
6522 
6523  inline T value() const
6524  {
6525  T result = T(0);
6526 
6527  if (initialiser_)
6528  initialiser_->value();
6529 
6530  if (incrementor_)
6531  {
6532  while (is_true(condition_))
6533  {
6534  try
6535  {
6536  result = loop_body_->value();
6537  }
6538  catch(const break_exception<T>& e)
6539  {
6540  return e.value;
6541  }
6542  catch(const continue_exception&)
6543  {}
6544 
6545  incrementor_->value();
6546  }
6547  }
6548  else
6549  {
6550  while (is_true(condition_))
6551  {
6552  try
6553  {
6554  result = loop_body_->value();
6555  }
6556  catch(const break_exception<T>& e)
6557  {
6558  return e.value;
6559  }
6560  catch(const continue_exception&)
6561  {}
6562  }
6563  }
6564 
6565  return result;
6566  }
6567 
6568  inline typename expression_node<T>::node_type type() const
6569  {
6571  }
6572 
6573  private:
6574 
6583  };
6584  #endif
6585 
6586  template <typename T>
6587  class switch_node : public expression_node<T>
6588  {
6589  public:
6590 
6592 
6593  template <typename Allocator,
6594  template <typename,typename> class Sequence>
6595  switch_node(const Sequence<expression_ptr,Allocator>& arg_list)
6596  {
6597  if (1 != (arg_list.size() & 1))
6598  return;
6599 
6600  arg_list_.resize(arg_list.size());
6601  delete_branch_.resize(arg_list.size());
6602 
6603  for (std::size_t i = 0; i < arg_list.size(); ++i)
6604  {
6605  if (arg_list[i])
6606  {
6607  arg_list_[i] = arg_list[i];
6608  delete_branch_[i] = static_cast<unsigned char>(branch_deletable(arg_list_[i]) ? 1 : 0);
6609  }
6610  else
6611  {
6612  arg_list_.clear();
6613  delete_branch_.clear();
6614  return;
6615  }
6616  }
6617  }
6618 
6620  {
6621  for (std::size_t i = 0; i < arg_list_.size(); ++i)
6622  {
6623  if (arg_list_[i] && delete_branch_[i])
6624  {
6625  destroy_node(arg_list_[i]);
6626  }
6627  }
6628  }
6629 
6630  inline T value() const
6631  {
6632  if (!arg_list_.empty())
6633  {
6634  const std::size_t upper_bound = (arg_list_.size() - 1);
6635 
6636  for (std::size_t i = 0; i < upper_bound; i += 2)
6637  {
6638  expression_ptr condition = arg_list_[i ];
6639  expression_ptr consequent = arg_list_[i + 1];
6640 
6641  if (is_true(condition))
6642  {
6643  return consequent->value();
6644  }
6645  }
6646 
6647  return arg_list_[upper_bound]->value();
6648  }
6649  else
6650  return std::numeric_limits<T>::quiet_NaN();
6651  }
6652 
6653  inline typename expression_node<T>::node_type type() const
6654  {
6656  }
6657 
6658  protected:
6659 
6660  std::vector<expression_ptr> arg_list_;
6661  std::vector<unsigned char> delete_branch_;
6662  };
6663 
6664  template <typename T, typename Switch_N>
6665  class switch_n_node : public switch_node<T>
6666  {
6667  public:
6668 
6670 
6671  template <typename Allocator,
6672  template <typename,typename> class Sequence>
6673  switch_n_node(const Sequence<expression_ptr,Allocator>& arg_list)
6674  : switch_node<T>(arg_list)
6675  {}
6676 
6677  inline T value() const
6678  {
6680  }
6681  };
6682 
6683  template <typename T>
6685  {
6686  public:
6687 
6689 
6690  template <typename Allocator,
6691  template <typename,typename> class Sequence>
6692  multi_switch_node(const Sequence<expression_ptr,Allocator>& arg_list)
6693  {
6694  if (0 != (arg_list.size() & 1))
6695  return;
6696 
6697  arg_list_.resize(arg_list.size());
6698  delete_branch_.resize(arg_list.size());
6699 
6700  for (std::size_t i = 0; i < arg_list.size(); ++i)
6701  {
6702  if (arg_list[i])
6703  {
6704  arg_list_[i] = arg_list[i];
6705  delete_branch_[i] = static_cast<unsigned char>(branch_deletable(arg_list_[i]) ? 1 : 0);
6706  }
6707  else
6708  {
6709  arg_list_.clear();
6710  delete_branch_.clear();
6711  return;
6712  }
6713  }
6714  }
6715 
6717  {
6718  for (std::size_t i = 0; i < arg_list_.size(); ++i)
6719  {
6720  if (arg_list_[i] && delete_branch_[i])
6721  {
6722  destroy_node(arg_list_[i]);
6723  }
6724  }
6725  }
6726 
6727  inline T value() const
6728  {
6729  T result = T(0);
6730 
6731  if (arg_list_.empty())
6732  {
6733  return std::numeric_limits<T>::quiet_NaN();
6734  }
6735 
6736  const std::size_t upper_bound = (arg_list_.size() - 1);
6737 
6738  for (std::size_t i = 0; i < upper_bound; i += 2)
6739  {
6740  expression_ptr condition = arg_list_[i ];
6741  expression_ptr consequent = arg_list_[i + 1];
6742 
6743  if (is_true(condition))
6744  {
6745  result = consequent->value();
6746  }
6747  }
6748 
6749  return result;
6750  }
6751 
6752  inline typename expression_node<T>::node_type type() const
6753  {
6755  }
6756 
6757  private:
6758 
6759  std::vector<expression_ptr> arg_list_;
6760  std::vector<unsigned char> delete_branch_;
6761  };
6762 
6763  template <typename T>
6765  {
6766  public:
6767 
6768  virtual ~ivariable()
6769  {}
6770 
6771  virtual T& ref() = 0;
6772  virtual const T& ref() const = 0;
6773  };
6774 
6775  template <typename T>
6776  class variable_node : public expression_node<T>,
6777  public ivariable <T>
6778  {
6779  public:
6780 
6781  static T null_value;
6782 
6783  explicit variable_node()
6784  : value_(&null_value)
6785  {}
6786 
6788  : value_(&v)
6789  {}
6790 
6791  inline bool operator <(const variable_node<T>& v) const
6792  {
6793  return this < (&v);
6794  }
6795 
6796  inline T value() const
6797  {
6798  return (*value_);
6799  }
6800 
6801  inline T& ref()
6802  {
6803  return (*value_);
6804  }
6805 
6806  inline const T& ref() const
6807  {
6808  return (*value_);
6809  }
6810 
6811  inline typename expression_node<T>::node_type type() const
6812  {
6814  }
6815 
6816  private:
6817 
6819  };
6820 
6821  template <typename T>
6822  T variable_node<T>::null_value = T(std::numeric_limits<T>::quiet_NaN());
6823 
6824  template <typename T>
6825  struct range_pack
6826  {
6828  typedef std::pair<std::size_t,std::size_t> cached_range_t;
6829 
6831  : n0_e (std::make_pair(false,expression_node_ptr(0))),
6832  n1_e (std::make_pair(false,expression_node_ptr(0))),
6833  n0_c (std::make_pair(false,0)),
6834  n1_c (std::make_pair(false,0)),
6835  cache(std::make_pair(0,0))
6836  {}
6837 
6838  void clear()
6839  {
6840  n0_e = std::make_pair(false,expression_node_ptr(0));
6841  n1_e = std::make_pair(false,expression_node_ptr(0));
6842  n0_c = std::make_pair(false,0);
6843  n1_c = std::make_pair(false,0);
6844  cache = std::make_pair(0,0);
6845  }
6846 
6847  void free()
6848  {
6849  if (n0_e.first && n0_e.second)
6850  {
6851  n0_e.first = false;
6852 
6853  if (
6854  !is_variable_node(n0_e.second) &&
6855  !is_string_node (n0_e.second)
6856  )
6857  {
6858  destroy_node(n0_e.second);
6859  }
6860  }
6861 
6862  if (n1_e.first && n1_e.second)
6863  {
6864  n1_e.first = false;
6865 
6866  if (
6867  !is_variable_node(n1_e.second) &&
6868  !is_string_node (n1_e.second)
6869  )
6870  {
6871  destroy_node(n1_e.second);
6872  }
6873  }
6874  }
6875 
6877  {
6878  return ( n0_c.first && n1_c.first) &&
6879  (!n0_e.first && !n1_e.first);
6880  }
6881 
6882  bool var_range()
6883  {
6884  return ( n0_e.first && n1_e.first) &&
6885  (!n0_c.first && !n1_c.first);
6886  }
6887 
6888  bool operator() (std::size_t& r0, std::size_t& r1, const std::size_t& size = std::numeric_limits<std::size_t>::max()) const
6889  {
6890  if (n0_c.first)
6891  r0 = n0_c.second;
6892  else if (n0_e.first)
6893  {
6894  T r0_value = n0_e.second->value();
6895 
6896  if (r0_value < 0)
6897  return false;
6898  else
6899  r0 = static_cast<std::size_t>(details::numeric::to_int64(r0_value));
6900  }
6901  else
6902  return false;
6903 
6904  if (n1_c.first)
6905  r1 = n1_c.second;
6906  else if (n1_e.first)
6907  {
6908  T r1_value = n1_e.second->value();
6909 
6910  if (r1_value < 0)
6911  return false;
6912  else
6913  r1 = static_cast<std::size_t>(details::numeric::to_int64(r1_value));
6914  }
6915  else
6916  return false;
6917 
6918  if (
6921  )
6922  {
6923  r1 = size - 1;
6924  }
6925 
6926  cache.first = r0;
6927  cache.second = r1;
6928 
6929  return (r0 <= r1);
6930  }
6931 
6932  inline std::size_t const_size() const
6933  {
6934  return (n1_c.second - n0_c.second + 1);
6935  }
6936 
6937  inline std::size_t cache_size() const
6938  {
6939  return (cache.second - cache.first + 1);
6940  }
6941 
6942  std::pair<bool,expression_node_ptr> n0_e;
6943  std::pair<bool,expression_node_ptr> n1_e;
6944  std::pair<bool,std::size_t > n0_c;
6945  std::pair<bool,std::size_t > n1_c;
6947  };
6948 
6949  template <typename T>
6950  class string_base_node;
6951 
6952  template <typename T>
6953  struct range_data_type
6954  {
6957 
6959  : range(0),
6960  data (0),
6961  size (0),
6962  type_size(0),
6963  str_node (0)
6964  {}
6965 
6967  void* data;
6968  std::size_t size;
6969  std::size_t type_size;
6971  };
6972 
6973  template <typename T> class vector_node;
6974 
6975  template <typename T>
6977  {
6978  public:
6979 
6982 
6984  {}
6985 
6986  virtual std::size_t size () const = 0;
6987 
6988  virtual vector_node_ptr vec() const = 0;
6989 
6990  virtual vector_node_ptr vec() = 0;
6991 
6992  virtual vds_t& vds () = 0;
6993 
6994  virtual const vds_t& vds () const = 0;
6995 
6996  virtual bool side_effect () const { return false; }
6997  };
6998 
6999  template <typename T>
7000  class vector_node : public expression_node <T>,
7001  public vector_interface<T>
7002  {
7003  public:
7004 
7009 
7011  : vector_holder_(vh),
7013  {
7015  }
7016 
7018  : vector_holder_(vh),
7019  vds_(vds)
7020  {}
7021 
7022  inline T value() const
7023  {
7024  return vds().data()[0];
7025  }
7026 
7028  {
7029  return const_cast<vector_node_ptr>(this);
7030  }
7031 
7033  {
7034  return this;
7035  }
7036 
7037  inline typename expression_node<T>::node_type type() const
7038  {
7040  }
7041 
7042  std::size_t size() const
7043  {
7044  return vds().size();
7045  }
7046 
7048  {
7049  return vds_;
7050  }
7051 
7052  const vds_t& vds() const
7053  {
7054  return vds_;
7055  }
7056 
7058  {
7059  return (*vector_holder_);
7060  }
7061 
7062  private:
7063 
7066  };
7067 
7068  template <typename T>
7070  public ivariable <T>
7071  {
7072  public:
7073 
7077 
7079  : index_(index),
7080  vec_holder_(vec_holder),
7081  vector_base_((*vec_holder)[0]),
7083  {}
7084 
7086  {
7087  if (index_ && index_deletable_)
7088  {
7090  }
7091  }
7092 
7093  inline T value() const
7094  {
7095  return *(vector_base_ + static_cast<std::size_t>(details::numeric::to_int64(index_->value())));
7096  }
7097 
7098  inline T& ref()
7099  {
7100  return *(vector_base_ + static_cast<std::size_t>(details::numeric::to_int64(index_->value())));
7101  }
7102 
7103  inline const T& ref() const
7104  {
7105  return *(vector_base_ + static_cast<std::size_t>(details::numeric::to_int64(index_->value())));
7106  }
7107 
7108  inline typename expression_node<T>::node_type type() const
7109  {
7111  }
7112 
7114  {
7115  return (*vec_holder_);
7116  }
7117 
7118  private:
7119 
7123  const bool index_deletable_;
7124  };
7125 
7126  template <typename T>
7128  public ivariable <T>
7129  {
7130  public:
7131 
7136 
7138  : index_(index),
7140  vector_holder_(vec_holder),
7141  vds_((*vector_holder_).size(),(*vector_holder_)[0])
7142  {
7144  }
7145 
7147  {
7148  if (index_ && index_deletable_)
7149  {
7151  }
7152  }
7153 
7154  inline T value() const
7155  {
7156  return *(vds_.data() + static_cast<std::size_t>(details::numeric::to_int64(index_->value())));
7157  }
7158 
7159  inline T& ref()
7160  {
7161  return *(vds_.data() + static_cast<std::size_t>(details::numeric::to_int64(index_->value())));
7162  }
7163 
7164  inline const T& ref() const
7165  {
7166  return *(vds_.data() + static_cast<std::size_t>(details::numeric::to_int64(index_->value())));
7167  }
7168 
7169  inline typename expression_node<T>::node_type type() const
7170  {
7172  }
7173 
7175  {
7176  return (*vector_holder_);
7177  }
7178 
7179  private:
7180 
7182  const bool index_deletable_;
7185  };
7186 
7187  template <typename T>
7189  public ivariable <T>
7190  {
7191  public:
7192 
7197 
7199  : index_(index),
7200  vector_holder_(vec_holder),
7201  vds_((*vector_holder_).size(),(*vector_holder_)[0])
7202  {
7204  }
7205 
7206  inline T value() const
7207  {
7208  return *(vds_.data() + index_);
7209  }
7210 
7211  inline T& ref()
7212  {
7213  return *(vds_.data() + index_);
7214  }
7215 
7216  inline const T& ref() const
7217  {
7218  return *(vds_.data() + index_);
7219  }
7220 
7221  inline typename expression_node<T>::node_type type() const
7222  {
7224  }
7225 
7227  {
7228  return (*vector_holder_);
7229  }
7230 
7231  private:
7232 
7233  const std::size_t index_;
7236  };
7237 
7238  template <typename T>
7240  {
7241  public:
7242 
7244 
7245  vector_assignment_node(T* vector_base,
7246  const std::size_t& size,
7247  const std::vector<expression_ptr>& initialiser_list,
7248  const bool single_value_initialse)
7249  : vector_base_(vector_base),
7250  initialiser_list_(initialiser_list),
7251  size_(size),
7252  single_value_initialse_(single_value_initialse)
7253  {}
7254 
7256  {
7257  for (std::size_t i = 0; i < initialiser_list_.size(); ++i)
7258  {
7260  {
7262  }
7263  }
7264  }
7265 
7266  inline T value() const
7267  {
7269  {
7270  for (std::size_t i = 0; i < size_; ++i)
7271  {
7272  *(vector_base_ + i) = initialiser_list_[0]->value();
7273  }
7274  }
7275  else
7276  {
7277  std::size_t il_size = initialiser_list_.size();
7278 
7279  for (std::size_t i = 0; i < il_size; ++i)
7280  {
7281  *(vector_base_ + i) = initialiser_list_[i]->value();
7282  }
7283 
7284  if (il_size < size_)
7285  {
7286  for (std::size_t i = il_size; i < size_; ++i)
7287  {
7288  *(vector_base_ + i) = T(0);
7289  }
7290  }
7291  }
7292 
7293  return *(vector_base_);
7294  }
7295 
7296  inline typename expression_node<T>::node_type type() const
7297  {
7299  }
7300 
7301  private:
7302 
7304 
7305  mutable T* vector_base_;
7306  std::vector<expression_ptr> initialiser_list_;
7307  const std::size_t size_;
7309  };
7310 
7311  template <typename T>
7312  class swap_node : public expression_node<T>
7313  {
7314  public:
7315 
7318 
7320  : var0_(var0),
7321  var1_(var1)
7322  {}
7323 
7324  inline T value() const
7325  {
7326  std::swap(var0_->ref(),var1_->ref());
7327  return var1_->ref();
7328  }
7329 
7330  inline typename expression_node<T>::node_type type() const
7331  {
7333  }
7334 
7335  private:
7336 
7339  };
7340 
7341  template <typename T>
7342  class swap_generic_node : public binary_node<T>
7343  {
7344  public:
7345 
7348 
7350  : binary_node<T>(details::e_swap, var0, var1),
7351  var0_(dynamic_cast<ivariable_ptr>(var0)),
7352  var1_(dynamic_cast<ivariable_ptr>(var1))
7353  {}
7354 
7355  inline T value() const
7356  {
7357  std::swap(var0_->ref(),var1_->ref());
7358  return var1_->ref();
7359  }
7360 
7361  inline typename expression_node<T>::node_type type() const
7362  {
7364  }
7365 
7366  private:
7367 
7370  };
7371 
7372  template <typename T>
7373  class swap_vecvec_node : public binary_node <T>,
7374  public vector_interface<T>
7375  {
7376  public:
7377 
7381 
7383  expression_ptr branch1)
7384  : binary_node<T>(details::e_swap, branch0, branch1),
7385  vec0_node_ptr_(0),
7386  vec1_node_ptr_(0),
7387  vec_size_ (0),
7388  initialised_ (false)
7389  {
7391  {
7392  vector_interface<T>* vi = reinterpret_cast<vector_interface<T>*>(0);
7393 
7394  if (0 != (vi = dynamic_cast<vector_interface<T>*>(binary_node<T>::branch_[0].first)))
7395  {
7396  vec0_node_ptr_ = vi->vec();
7397  vds() = vi->vds();
7398  }
7399  }
7400 
7402  {
7403  vector_interface<T>* vi = reinterpret_cast<vector_interface<T>*>(0);
7404 
7405  if (0 != (vi = dynamic_cast<vector_interface<T>*>(binary_node<T>::branch_[1].first)))
7406  {
7407  vec1_node_ptr_ = vi->vec();
7408  }
7409  }
7410 
7412  {
7413  vec_size_ = std::min(vec0_node_ptr_->vds().size(),
7414  vec1_node_ptr_->vds().size());
7415 
7416  initialised_ = true;
7417  }
7418  }
7419 
7420  inline T value() const
7421  {
7422  if (initialised_)
7423  {
7424  binary_node<T>::branch_[0].first->value();
7425  binary_node<T>::branch_[1].first->value();
7426 
7427  T* vec0 = vec0_node_ptr_->vds().data();
7428  T* vec1 = vec1_node_ptr_->vds().data();
7429 
7430  for (std::size_t i = 0; i < vec_size_; ++i)
7431  {
7432  std::swap(vec0[i],vec1[i]);
7433  }
7434 
7435  return vec1_node_ptr_->value();
7436  }
7437  else
7438  return std::numeric_limits<T>::quiet_NaN();
7439  }
7440 
7442  {
7443  return vec0_node_ptr_;
7444  }
7445 
7447  {
7448  return vec0_node_ptr_;
7449  }
7450 
7451  inline typename expression_node<T>::node_type type() const
7452  {
7454  }
7455 
7456  std::size_t size() const
7457  {
7458  return vec_size_;
7459  }
7460 
7462  {
7463  return vds_;
7464  }
7465 
7466  const vds_t& vds() const
7467  {
7468  return vds_;
7469  }
7470 
7471  private:
7472 
7475  std::size_t vec_size_;
7478  };
7479 
7480  #ifndef exprtk_disable_string_capabilities
7481  template <typename T>
7482  class stringvar_node : public expression_node <T>,
7483  public string_base_node<T>,
7484  public range_interface <T>
7485  {
7486  public:
7487 
7489 
7490  static std::string null_value;
7491 
7492  explicit stringvar_node()
7493  : value_(&null_value)
7494  {}
7495 
7496  explicit stringvar_node(std::string& v)
7497  : value_(&v)
7498  {
7499  rp_.n0_c = std::make_pair<bool,std::size_t>(true,0);
7500  rp_.n1_c = std::make_pair<bool,std::size_t>(true,v.size() - 1);
7501  rp_.cache.first = rp_.n0_c.second;
7502  rp_.cache.second = rp_.n1_c.second;
7503  }
7504 
7505  inline bool operator <(const stringvar_node<T>& v) const
7506  {
7507  return this < (&v);
7508  }
7509 
7510  inline T value() const
7511  {
7512  rp_.n1_c.second = (*value_).size() - 1;
7513  rp_.cache.second = rp_.n1_c.second;
7514 
7515  return std::numeric_limits<T>::quiet_NaN();
7516  }
7517 
7518  std::string str() const
7519  {
7520  return ref();
7521  }
7522 
7523  char_cptr base() const
7524  {
7525  return &(*value_)[0];
7526  }
7527 
7528  std::size_t size() const
7529  {
7530  return ref().size();
7531  }
7532 
7533  std::string& ref()
7534  {
7535  return (*value_);
7536  }
7537 
7538  const std::string& ref() const
7539  {
7540  return (*value_);
7541  }
7542 
7544  {
7545  return rp_;
7546  }
7547 
7548  const range_t& range_ref() const
7549  {
7550  return rp_;
7551  }
7552 
7553  inline typename expression_node<T>::node_type type() const
7554  {
7556  }
7557 
7558  private:
7559 
7560  std::string* value_;
7561  mutable range_t rp_;
7562  };
7563 
7564  template <typename T>
7565  std::string stringvar_node<T>::null_value = std::string("");
7566 
7567  template <typename T>
7569  public string_base_node<T>,
7570  public range_interface <T>
7571  {
7572  public:
7573 
7575 
7576  static std::string null_value;
7577 
7578  explicit string_range_node(std::string& v, const range_t& rp)
7579  : value_(&v),
7580  rp_(rp)
7581  {}
7582 
7584  {
7585  rp_.free();
7586  }
7587 
7588  inline bool operator <(const string_range_node<T>& v) const
7589  {
7590  return this < (&v);
7591  }
7592 
7593  inline T value() const
7594  {
7595  return std::numeric_limits<T>::quiet_NaN();
7596  }
7597 
7598  inline std::string str() const
7599  {
7600  return (*value_);
7601  }
7602 
7603  char_cptr base() const
7604  {
7605  return &(*value_)[0];
7606  }
7607 
7608  std::size_t size() const
7609  {
7610  return ref().size();
7611  }
7612 
7613  inline range_t range() const
7614  {
7615  return rp_;
7616  }
7617 
7618  inline virtual std::string& ref()
7619  {
7620  return (*value_);
7621  }
7622 
7623  inline virtual const std::string& ref() const
7624  {
7625  return (*value_);
7626  }
7627 
7628  inline range_t& range_ref()
7629  {
7630  return rp_;
7631  }
7632 
7633  inline const range_t& range_ref() const
7634  {
7635  return rp_;
7636  }
7637 
7638  inline typename expression_node<T>::node_type type() const
7639  {
7641  }
7642 
7643  private:
7644 
7645  std::string* value_;
7647  };
7648 
7649  template <typename T>
7650  std::string string_range_node<T>::null_value = std::string("");
7651 
7652  template <typename T>
7654  public string_base_node<T>,
7655  public range_interface <T>
7656  {
7657  public:
7658 
7660 
7661  explicit const_string_range_node(const std::string& v, const range_t& rp)
7662  : value_(v),
7663  rp_(rp)
7664  {}
7665 
7667  {
7668  rp_.free();
7669  }
7670 
7671  inline T value() const
7672  {
7673  return std::numeric_limits<T>::quiet_NaN();
7674  }
7675 
7676  std::string str() const
7677  {
7678  return value_;
7679  }
7680 
7681  char_cptr base() const
7682  {
7683  return value_.data();
7684  }
7685 
7686  std::size_t size() const
7687  {
7688  return value_.size();
7689  }
7690 
7691  range_t range() const
7692  {
7693  return rp_;
7694  }
7695 
7697  {
7698  return rp_;
7699  }
7700 
7701  const range_t& range_ref() const
7702  {
7703  return rp_;
7704  }
7705 
7706  inline typename expression_node<T>::node_type type() const
7707  {
7709  }
7710 
7711  private:
7712 
7714 
7715  const std::string value_;
7717  };
7718 
7719  template <typename T>
7721  public string_base_node<T>,
7722  public range_interface <T>
7723  {
7724  public:
7725 
7730  typedef range_t* range_ptr;
7733 
7735  : initialised_(false),
7736  branch_(str_branch),
7738  str_base_ptr_ (0),
7739  str_range_ptr_(0),
7740  base_range_(brange)
7741  {
7742  range_.n0_c = std::make_pair<bool,std::size_t>(true,0);
7743  range_.n1_c = std::make_pair<bool,std::size_t>(true,0);
7744  range_.cache.first = range_.n0_c.second;
7745  range_.cache.second = range_.n1_c.second;
7746 
7748  {
7749  str_base_ptr_ = dynamic_cast<str_base_ptr>(branch_);
7750 
7751  if (0 == str_base_ptr_)
7752  return;
7753 
7754  str_range_ptr_ = dynamic_cast<irange_ptr>(branch_);
7755 
7756  if (0 == str_range_ptr_)
7757  return;
7758  }
7759 
7761  }
7762 
7764  {
7765  base_range_.free();
7766 
7767  if (branch_ && branch_deletable_)
7768  {
7770  }
7771  }
7772 
7773  inline T value() const
7774  {
7775  if (initialised_)
7776  {
7777  branch_->value();
7778 
7779  std::size_t str_r0 = 0;
7780  std::size_t str_r1 = 0;
7781 
7782  std::size_t r0 = 0;
7783  std::size_t r1 = 0;
7784 
7785  range_t& range = str_range_ptr_->range_ref();
7786 
7787  const std::size_t base_str_size = str_base_ptr_->size();
7788 
7789  if (
7790  range (str_r0,str_r1,base_str_size) &&
7791  base_range_( r0, r1,base_str_size)
7792  )
7793  {
7794  const std::size_t size = (r1 - r0) + 1;
7795 
7796  range_.n1_c.second = size - 1;
7797  range_.cache.second = range_.n1_c.second;
7798 
7799  value_.assign(str_base_ptr_->base() + str_r0 + r0, size);
7800  }
7801  }
7802 
7803  return std::numeric_limits<T>::quiet_NaN();
7804  }
7805 
7806  std::string str() const
7807  {
7808  return value_;
7809  }
7810 
7811  char_cptr base() const
7812  {
7813  return &value_[0];
7814  }
7815 
7816  std::size_t size() const
7817  {
7818  return value_.size();
7819  }
7820 
7822  {
7823  return range_;
7824  }
7825 
7826  const range_t& range_ref() const
7827  {
7828  return range_;
7829  }
7830 
7831  inline typename expression_node<T>::node_type type() const
7832  {
7834  }
7835 
7836  private:
7837 
7840  const bool branch_deletable_;
7844  mutable range_t range_;
7845  mutable std::string value_;
7846  };
7847 
7848  template <typename T>
7849  class string_concat_node : public binary_node <T>,
7850  public string_base_node<T>,
7851  public range_interface <T>
7852  {
7853  public:
7854 
7858  typedef range_t* range_ptr;
7861 
7863  expression_ptr branch0,
7864  expression_ptr branch1)
7865  : binary_node<T>(opr, branch0, branch1),
7866  initialised_(false),
7867  str0_base_ptr_ (0),
7868  str1_base_ptr_ (0),
7869  str0_range_ptr_(0),
7870  str1_range_ptr_(0)
7871  {
7872  range_.n0_c = std::make_pair<bool,std::size_t>(true,0);
7873  range_.n1_c = std::make_pair<bool,std::size_t>(true,0);
7874 
7875  range_.cache.first = range_.n0_c.second;
7876  range_.cache.second = range_.n1_c.second;
7877 
7879  {
7880  str0_base_ptr_ = dynamic_cast<str_base_ptr>(binary_node<T>::branch_[0].first);
7881 
7882  if (0 == str0_base_ptr_)
7883  return;
7884 
7885  str0_range_ptr_ = dynamic_cast<irange_ptr>(binary_node<T>::branch_[0].first);
7886 
7887  if (0 == str0_range_ptr_)
7888  return;
7889  }
7890 
7892  {
7893  str1_base_ptr_ = dynamic_cast<str_base_ptr>(binary_node<T>::branch_[1].first);
7894 
7895  if (0 == str1_base_ptr_)
7896  return;
7897 
7898  str1_range_ptr_ = dynamic_cast<irange_ptr>(binary_node<T>::branch_[1].first);
7899 
7900  if (0 == str1_range_ptr_)
7901  return;
7902  }
7903 
7905  str1_base_ptr_ &&
7906  str0_range_ptr_ &&
7907  str1_range_ptr_ ;
7908  }
7909 
7910  inline T value() const
7911  {
7912  if (initialised_)
7913  {
7914  binary_node<T>::branch_[0].first->value();
7915  binary_node<T>::branch_[1].first->value();
7916 
7917  std::size_t str0_r0 = 0;
7918  std::size_t str0_r1 = 0;
7919 
7920  std::size_t str1_r0 = 0;
7921  std::size_t str1_r1 = 0;
7922 
7923  range_t& range0 = str0_range_ptr_->range_ref();
7924  range_t& range1 = str1_range_ptr_->range_ref();
7925 
7926  if (
7927  range0(str0_r0,str0_r1,str0_base_ptr_->size()) &&
7928  range1(str1_r0,str1_r1,str1_base_ptr_->size())
7929  )
7930  {
7931  const std::size_t size0 = (str0_r1 - str0_r0) + 1;
7932  const std::size_t size1 = (str1_r1 - str1_r0) + 1;
7933 
7934  value_.assign(str0_base_ptr_->base() + str0_r0, size0);
7935  value_.append(str1_base_ptr_->base() + str1_r0, size1);
7936 
7937  range_.n1_c.second = value_.size() - 1;
7938  range_.cache.second = range_.n1_c.second;
7939  }
7940  }
7941 
7942  return std::numeric_limits<T>::quiet_NaN();
7943  }
7944 
7945  std::string str() const
7946  {
7947  return value_;
7948  }
7949 
7950  char_cptr base() const
7951  {
7952  return &value_[0];
7953  }
7954 
7955  std::size_t size() const
7956  {
7957  return value_.size();
7958  }
7959 
7961  {
7962  return range_;
7963  }
7964 
7965  const range_t& range_ref() const
7966  {
7967  return range_;
7968  }
7969 
7970  inline typename expression_node<T>::node_type type() const
7971  {
7973  }
7974 
7975  private:
7976 
7982  mutable range_t range_;
7983  mutable std::string value_;
7984  };
7985 
7986  template <typename T>
7987  class swap_string_node : public binary_node <T>,
7988  public string_base_node<T>,
7989  public range_interface <T>
7990  {
7991  public:
7992 
7997  typedef range_t* range_ptr;
8000 
8002  : binary_node<T>(details::e_swap, branch0, branch1),
8003  initialised_(false),
8004  str0_node_ptr_(0),
8005  str1_node_ptr_(0)
8006  {
8008  {
8009  str0_node_ptr_ = static_cast<strvar_node_ptr>(binary_node<T>::branch_[0].first);
8010  }
8011 
8013  {
8014  str1_node_ptr_ = static_cast<strvar_node_ptr>(binary_node<T>::branch_[1].first);
8015  }
8016 
8018  }
8019 
8020  inline T value() const
8021  {
8022  if (initialised_)
8023  {
8024  binary_node<T>::branch_[0].first->value();
8025  binary_node<T>::branch_[1].first->value();
8026 
8028  }
8029 
8030  return std::numeric_limits<T>::quiet_NaN();
8031  }
8032 
8033  std::string str() const
8034  {
8035  return str0_node_ptr_->str();
8036  }
8037 
8038  char_cptr base() const
8039  {
8040  return str0_node_ptr_->base();
8041  }
8042 
8043  std::size_t size() const
8044  {
8045  return str0_node_ptr_->size();
8046  }
8047 
8049  {
8050  return str0_node_ptr_->range_ref();
8051  }
8052 
8053  const range_t& range_ref() const
8054  {
8055  return str0_node_ptr_->range_ref();
8056  }
8057 
8058  inline typename expression_node<T>::node_type type() const
8059  {
8061  }
8062 
8063  private:
8064 
8068  };
8069 
8070  template <typename T>
8072  {
8073  public:
8074 
8078  typedef range_t* range_ptr;
8081 
8083  expression_ptr branch1)
8084  : binary_node<T>(details::e_default, branch0, branch1),
8085  str0_base_ptr_ (0),
8086  str1_base_ptr_ (0),
8087  str0_range_ptr_(0),
8088  str1_range_ptr_(0),
8089  initialised_(false)
8090  {
8092  {
8093  str0_base_ptr_ = dynamic_cast<str_base_ptr>(binary_node<T>::branch_[0].first);
8094 
8095  if (0 == str0_base_ptr_)
8096  return;
8097 
8098  irange_ptr range = dynamic_cast<irange_ptr>(binary_node<T>::branch_[0].first);
8099 
8100  if (0 == range)
8101  return;
8102 
8103  str0_range_ptr_ = &(range->range_ref());
8104  }
8105 
8107  {
8108  str1_base_ptr_ = dynamic_cast<str_base_ptr>(binary_node<T>::branch_[1].first);
8109 
8110  if (0 == str1_base_ptr_)
8111  return;
8112 
8113  irange_ptr range = dynamic_cast<irange_ptr>(binary_node<T>::branch_[1].first);
8114 
8115  if (0 == range)
8116  return;
8117 
8118  str1_range_ptr_ = &(range->range_ref());
8119  }
8120 
8122  str1_base_ptr_ &&
8123  str0_range_ptr_ &&
8124  str1_range_ptr_ ;
8125  }
8126 
8127  inline T value() const
8128  {
8129  if (initialised_)
8130  {
8131  binary_node<T>::branch_[0].first->value();
8132  binary_node<T>::branch_[1].first->value();
8133 
8134  std::size_t str0_r0 = 0;
8135  std::size_t str0_r1 = 0;
8136 
8137  std::size_t str1_r0 = 0;
8138  std::size_t str1_r1 = 0;
8139 
8140  range_t& range0 = (*str0_range_ptr_);
8141  range_t& range1 = (*str1_range_ptr_);
8142 
8143  if (
8144  range0(str0_r0,str0_r1,str0_base_ptr_->size()) &&
8145  range1(str1_r0,str1_r1,str1_base_ptr_->size())
8146  )
8147  {
8148  const std::size_t size0 = range0.cache_size();
8149  const std::size_t size1 = range1.cache_size();
8150  const std::size_t max_size = std::min(size0,size1);
8151 
8152  char_ptr s0 = const_cast<char_ptr>(str0_base_ptr_->base() + str0_r0);
8153  char_ptr s1 = const_cast<char_ptr>(str1_base_ptr_->base() + str1_r0);
8154 
8155  loop_unroll::details lud(max_size);
8156  char_cptr upper_bound = s0 + lud.upper_bound;
8157 
8158  while (s0 < upper_bound)
8159  {
8160  #define exprtk_loop(N) \
8161  std::swap(s0[N], s1[N]); \
8162 
8163  exprtk_loop( 0) exprtk_loop( 1)
8164  exprtk_loop( 2) exprtk_loop( 3)
8165  #ifndef exprtk_disable_superscalar_unroll
8166  exprtk_loop( 4) exprtk_loop( 5)
8167  exprtk_loop( 6) exprtk_loop( 7)
8168  exprtk_loop( 8) exprtk_loop( 9)
8169  exprtk_loop(10) exprtk_loop(11)
8170  exprtk_loop(12) exprtk_loop(13)
8171  exprtk_loop(14) exprtk_loop(15)
8172  #endif
8173 
8174  s0 += lud.batch_size;
8175  s1 += lud.batch_size;
8176  }
8177 
8178  int i = 0;
8179 
8181  switch (lud.remainder)
8182  {
8183  #define case_stmt(N) \
8184  case N : { std::swap(s0[i],s1[i]); ++i; } \
8185 
8186  #ifndef exprtk_disable_superscalar_unroll
8187  case_stmt(15) case_stmt(14)
8188  case_stmt(13) case_stmt(12)
8189  case_stmt(11) case_stmt(10)
8190  case_stmt( 9) case_stmt( 8)
8191  case_stmt( 7) case_stmt( 6)
8192  case_stmt( 5) case_stmt( 4)
8193  #endif
8194  case_stmt( 3) case_stmt( 2)
8195  case_stmt( 1)
8196  }
8198 
8199  #undef exprtk_loop
8200  #undef case_stmt
8201  }
8202  }
8203 
8204  return std::numeric_limits<T>::quiet_NaN();
8205  }
8206 
8207  inline typename expression_node<T>::node_type type() const
8208  {
8210  }
8211 
8212  private:
8213 
8216 
8222  };
8223 
8224  template <typename T>
8226  {
8227  public:
8228 
8229  static std::string null_value;
8230 
8232  : value_(&null_value)
8233  {}
8234 
8235  explicit stringvar_size_node(std::string& v)
8236  : value_(&v)
8237  {}
8238 
8239  inline T value() const
8240  {
8241  return T((*value_).size());
8242  }
8243 
8244  inline typename expression_node<T>::node_type type() const
8245  {
8247  }
8248 
8249  private:
8250 
8251  std::string* value_;
8252  };
8253 
8254  template <typename T>
8255  std::string stringvar_size_node<T>::null_value = std::string("");
8256 
8257  template <typename T>
8259  {
8260  public:
8261 
8264 
8266  : branch_(brnch),
8268  str_base_ptr_(0)
8269  {
8271  {
8272  str_base_ptr_ = dynamic_cast<str_base_ptr>(branch_);
8273 
8274  if (0 == str_base_ptr_)
8275  return;
8276  }
8277  }
8278 
8280  {
8281  if (branch_ && branch_deletable_)
8282  {
8284  }
8285  }
8286 
8287  inline T value() const
8288  {
8289  T result = std::numeric_limits<T>::quiet_NaN();
8290 
8291  if (str_base_ptr_)
8292  {
8293  branch_->value();
8294  result = T(str_base_ptr_->size());
8295  }
8296 
8297  return result;
8298  }
8299 
8300  inline typename expression_node<T>::node_type type() const
8301  {
8303  }
8304 
8305  private:
8306 
8308  const bool branch_deletable_;
8310  };
8311 
8313  {
8314  static inline void execute(std::string& s, char_cptr data, const std::size_t size)
8315  { s.assign(data,size); }
8316  };
8317 
8319  {
8320  static inline void execute(std::string& s, char_cptr data, const std::size_t size)
8321  { s.append(data,size); }
8322  };
8323 
8324  template <typename T, typename AssignmentProcess = asn_assignment>
8326  public string_base_node<T>,
8327  public range_interface <T>
8328  {
8329  public:
8330 
8335  typedef range_t* range_ptr;
8338 
8340  expression_ptr branch0,
8341  expression_ptr branch1)
8342  : binary_node<T>(opr, branch0, branch1),
8343  initialised_(false),
8344  str0_base_ptr_ (0),
8345  str1_base_ptr_ (0),
8346  str0_node_ptr_ (0),
8347  str1_range_ptr_(0)
8348  {
8350  {
8351  str0_node_ptr_ = static_cast<strvar_node_ptr>(binary_node<T>::branch_[0].first);
8352 
8353  str0_base_ptr_ = dynamic_cast<str_base_ptr>(binary_node<T>::branch_[0].first);
8354  }
8355 
8357  {
8358  str1_base_ptr_ = dynamic_cast<str_base_ptr>(binary_node<T>::branch_[1].first);
8359 
8360  if (0 == str1_base_ptr_)
8361  return;
8362 
8363  irange_ptr range = dynamic_cast<irange_ptr>(binary_node<T>::branch_[1].first);
8364 
8365  if (0 == range)
8366  return;
8367 
8368  str1_range_ptr_ = &(range->range_ref());
8369  }
8370 
8372  str1_base_ptr_ &&
8373  str0_node_ptr_ &&
8374  str1_range_ptr_ ;
8375  }
8376 
8377  inline T value() const
8378  {
8379  if (initialised_)
8380  {
8381  binary_node<T>::branch_[1].first->value();
8382 
8383  std::size_t r0 = 0;
8384  std::size_t r1 = 0;
8385 
8386  range_t& range = (*str1_range_ptr_);
8387 
8388  if (range(r0, r1, str1_base_ptr_->size()))
8389  {
8390  AssignmentProcess::execute(str0_node_ptr_->ref(),
8391  str1_base_ptr_->base() + r0,
8392  (r1 - r0) + 1);
8393 
8394  binary_node<T>::branch_[0].first->value();
8395  }
8396  }
8397 
8398  return std::numeric_limits<T>::quiet_NaN();
8399  }
8400 
8401  std::string str() const
8402  {
8403  return str0_node_ptr_->str();
8404  }
8405 
8406  char_cptr base() const
8407  {
8408  return str0_node_ptr_->base();
8409  }
8410 
8411  std::size_t size() const
8412  {
8413  return str0_node_ptr_->size();
8414  }
8415 
8417  {
8418  return str0_node_ptr_->range_ref();
8419  }
8420 
8421  const range_t& range_ref() const
8422  {
8423  return str0_node_ptr_->range_ref();
8424  }
8425 
8426  inline typename expression_node<T>::node_type type() const
8427  {
8429  }
8430 
8431  private:
8432 
8438  };
8439 
8440  template <typename T, typename AssignmentProcess = asn_assignment>
8442  public string_base_node<T>,
8443  public range_interface <T>
8444  {
8445  public:
8446 
8451  typedef range_t* range_ptr;
8454 
8456  expression_ptr branch0,
8457  expression_ptr branch1)
8458  : binary_node<T>(opr, branch0, branch1),
8459  initialised_(false),
8460  str0_base_ptr_ (0),
8461  str1_base_ptr_ (0),
8462  str0_node_ptr_ (0),
8463  str0_range_ptr_(0),
8464  str1_range_ptr_(0)
8465  {
8467  {
8468  str0_node_ptr_ = static_cast<strvar_node_ptr>(binary_node<T>::branch_[0].first);
8469 
8470  str0_base_ptr_ = dynamic_cast<str_base_ptr>(binary_node<T>::branch_[0].first);
8471 
8472  irange_ptr range = dynamic_cast<irange_ptr>(binary_node<T>::branch_[0].first);
8473 
8474  if (0 == range)
8475  return;
8476 
8477  str0_range_ptr_ = &(range->range_ref());
8478  }
8479 
8481  {
8482  str1_base_ptr_ = dynamic_cast<str_base_ptr>(binary_node<T>::branch_[1].first);
8483 
8484  if (0 == str1_base_ptr_)
8485  return;
8486 
8487  irange_ptr range = dynamic_cast<irange_ptr>(binary_node<T>::branch_[1].first);
8488 
8489  if (0 == range)
8490  return;
8491 
8492  str1_range_ptr_ = &(range->range_ref());
8493  }
8494 
8496  str1_base_ptr_ &&
8497  str0_node_ptr_ &&
8498  str0_range_ptr_ &&
8499  str1_range_ptr_ ;
8500  }
8501 
8502  inline T value() const
8503  {
8504  if (initialised_)
8505  {
8506  binary_node<T>::branch_[0].first->value();
8507  binary_node<T>::branch_[1].first->value();
8508 
8509  std::size_t s0_r0 = 0;
8510  std::size_t s0_r1 = 0;
8511 
8512  std::size_t s1_r0 = 0;
8513  std::size_t s1_r1 = 0;
8514 
8515  range_t& range0 = (*str0_range_ptr_);
8516  range_t& range1 = (*str1_range_ptr_);
8517 
8518  if (
8519  range0(s0_r0, s0_r1, str0_base_ptr_->size()) &&
8520  range1(s1_r0, s1_r1, str1_base_ptr_->size())
8521  )
8522  {
8523  std::size_t size = std::min((s0_r1 - s0_r0),(s1_r1 - s1_r0)) + 1;
8524 
8525  std::copy(str1_base_ptr_->base() + s1_r0,
8526  str1_base_ptr_->base() + s1_r0 + size,
8527  const_cast<char_ptr>(base() + s0_r0));
8528  }
8529  }
8530 
8531  return std::numeric_limits<T>::quiet_NaN();
8532  }
8533 
8534  std::string str() const
8535  {
8536  return str0_node_ptr_->str();
8537  }
8538 
8539  char_cptr base() const
8540  {
8541  return str0_node_ptr_->base();
8542  }
8543 
8544  std::size_t size() const
8545  {
8546  return str0_node_ptr_->size();
8547  }
8548 
8550  {
8551  return str0_node_ptr_->range_ref();
8552  }
8553 
8554  const range_t& range_ref() const
8555  {
8556  return str0_node_ptr_->range_ref();
8557  }
8558 
8559  inline typename expression_node<T>::node_type type() const
8560  {
8562  }
8563 
8564  private:
8565 
8572  };
8573 
8574  template <typename T>
8576  public string_base_node<T>,
8577  public range_interface <T>
8578  {
8579  public:
8580 
8584  typedef range_t* range_ptr;
8587 
8589  expression_ptr consequent,
8590  expression_ptr alternative)
8591  : trinary_node<T>(details::e_default,consequent,alternative,test),
8592  initialised_(false),
8593  str0_base_ptr_ (0),
8594  str1_base_ptr_ (0),
8595  str0_range_ptr_(0),
8596  str1_range_ptr_(0),
8597  test_ (test),
8598  consequent_ (consequent),
8599  alternative_(alternative)
8600  {
8601  range_.n0_c = std::make_pair<bool,std::size_t>(true,0);
8602  range_.n1_c = std::make_pair<bool,std::size_t>(true,0);
8603 
8604  range_.cache.first = range_.n0_c.second;
8605  range_.cache.second = range_.n1_c.second;
8606 
8608  {
8609  str0_base_ptr_ = dynamic_cast<str_base_ptr>(trinary_node<T>::branch_[0].first);
8610 
8611  if (0 == str0_base_ptr_)
8612  return;
8613 
8614  str0_range_ptr_ = dynamic_cast<irange_ptr>(trinary_node<T>::branch_[0].first);
8615 
8616  if (0 == str0_range_ptr_)
8617  return;
8618  }
8619 
8621  {
8622  str1_base_ptr_ = dynamic_cast<str_base_ptr>(trinary_node<T>::branch_[1].first);
8623 
8624  if (0 == str1_base_ptr_)
8625  return;
8626 
8627  str1_range_ptr_ = dynamic_cast<irange_ptr>(trinary_node<T>::branch_[1].first);
8628 
8629  if (0 == str1_range_ptr_)
8630  return;
8631  }
8632 
8634  str1_base_ptr_ &&
8635  str0_range_ptr_ &&
8636  str1_range_ptr_ ;
8637 
8638  }
8639 
8640  inline T value() const
8641  {
8642  if (initialised_)
8643  {
8644  std::size_t r0 = 0;
8645  std::size_t r1 = 0;
8646 
8647  if (is_true(test_))
8648  {
8649  consequent_->value();
8650 
8651  range_t& range = str0_range_ptr_->range_ref();
8652 
8653  if (range(r0, r1, str0_base_ptr_->size()))
8654  {
8655  const std::size_t size = (r1 - r0) + 1;
8656 
8657  value_.assign(str0_base_ptr_->base() + r0, size);
8658 
8659  range_.n1_c.second = value_.size() - 1;
8660  range_.cache.second = range_.n1_c.second;
8661 
8662  return T(1);
8663  }
8664  }
8665  else
8666  {
8667  alternative_->value();
8668 
8669  range_t& range = str1_range_ptr_->range_ref();
8670 
8671  if (range(r0, r1, str1_base_ptr_->size()))
8672  {
8673  const std::size_t size = (r1 - r0) + 1;
8674 
8675  value_.assign(str1_base_ptr_->base() + r0, size);
8676 
8677  range_.n1_c.second = value_.size() - 1;
8678  range_.cache.second = range_.n1_c.second;
8679 
8680  return T(0);
8681  }
8682  }
8683  }
8684 
8685  return std::numeric_limits<T>::quiet_NaN();
8686  }
8687 
8688  std::string str() const
8689  {
8690  return value_;
8691  }
8692 
8693  char_cptr base() const
8694  {
8695  return &value_[0];
8696  }
8697 
8698  std::size_t size() const
8699  {
8700  return value_.size();
8701  }
8702 
8704  {
8705  return range_;
8706  }
8707 
8708  const range_t& range_ref() const
8709  {
8710  return range_;
8711  }
8712 
8713  inline typename expression_node<T>::node_type type() const
8714  {
8716  }
8717 
8718  private:
8719 
8725  mutable range_t range_;
8726  mutable std::string value_;
8727 
8731  };
8732 
8733  template <typename T>
8735  public string_base_node<T>,
8736  public range_interface <T>
8737  {
8738  public:
8739 
8743  typedef range_t* range_ptr;
8746 
8748  expression_ptr consequent)
8749  : binary_node<T>(details::e_default, consequent, test),
8750  initialised_(false),
8751  str0_base_ptr_ (0),
8752  str0_range_ptr_(0),
8753  test_ (test),
8754  consequent_(consequent)
8755  {
8756  range_.n0_c = std::make_pair<bool,std::size_t>(true,0);
8757  range_.n1_c = std::make_pair<bool,std::size_t>(true,0);
8758 
8759  range_.cache.first = range_.n0_c.second;
8760  range_.cache.second = range_.n1_c.second;
8761 
8763  {
8764  str0_base_ptr_ = dynamic_cast<str_base_ptr>(binary_node<T>::branch_[0].first);
8765 
8766  if (0 == str0_base_ptr_)
8767  return;
8768 
8769  str0_range_ptr_ = dynamic_cast<irange_ptr>(binary_node<T>::branch_[0].first);
8770 
8771  if (0 == str0_range_ptr_)
8772  return;
8773  }
8774 
8776  }
8777 
8778  inline T value() const
8779  {
8780  if (initialised_)
8781  {
8782  if (is_true(test_))
8783  {
8784  consequent_->value();
8785 
8786  range_t& range = str0_range_ptr_->range_ref();
8787 
8788  std::size_t r0 = 0;
8789  std::size_t r1 = 0;
8790 
8791  if (range(r0, r1, str0_base_ptr_->size()))
8792  {
8793  const std::size_t size = (r1 - r0) + 1;
8794 
8795  value_.assign(str0_base_ptr_->base() + r0, size);
8796 
8797  range_.n1_c.second = value_.size() - 1;
8798  range_.cache.second = range_.n1_c.second;
8799 
8800  return T(1);
8801  }
8802  }
8803  }
8804 
8805  return std::numeric_limits<T>::quiet_NaN();
8806  }
8807 
8808  std::string str() const
8809  {
8810  return value_;
8811  }
8812 
8813  char_cptr base() const
8814  {
8815  return &value_[0];
8816  }
8817 
8818  std::size_t size() const
8819  {
8820  return value_.size();
8821  }
8822 
8824  {
8825  return range_;
8826  }
8827 
8828  const range_t& range_ref() const
8829  {
8830  return range_;
8831  }
8832 
8833  inline typename expression_node<T>::node_type type() const
8834  {
8836  }
8837 
8838  private:
8839 
8843  mutable range_t range_;
8844  mutable std::string value_;
8845 
8848  };
8849 
8850  template <typename T, typename VarArgFunction>
8851  class str_vararg_node : public expression_node <T>,
8852  public string_base_node<T>,
8853  public range_interface <T>
8854  {
8855  public:
8856 
8860  typedef range_t* range_ptr;
8863 
8864  template <typename Allocator,
8865  template <typename,typename> class Sequence>
8866  str_vararg_node(const Sequence<expression_ptr,Allocator>& arg_list)
8867  : final_node_(arg_list.back()),
8869  initialised_(false),
8870  str_base_ptr_ (0),
8871  str_range_ptr_(0)
8872  {
8873  if (0 == final_node_)
8874  return;
8876  return;
8877 
8878  str_base_ptr_ = dynamic_cast<str_base_ptr>(final_node_);
8879 
8880  if (0 == str_base_ptr_)
8881  return;
8882 
8883  str_range_ptr_ = dynamic_cast<irange_ptr>(final_node_);
8884 
8885  if (0 == str_range_ptr_)
8886  return;
8887 
8889 
8890  if (arg_list.size() > 1)
8891  {
8892  const std::size_t arg_list_size = arg_list.size() - 1;
8893 
8894  arg_list_.resize(arg_list_size);
8895  delete_branch_.resize(arg_list_size);
8896 
8897  for (std::size_t i = 0; i < arg_list_size; ++i)
8898  {
8899  if (arg_list[i])
8900  {
8901  arg_list_[i] = arg_list[i];
8902  delete_branch_[i] = static_cast<unsigned char>(branch_deletable(arg_list_[i]) ? 1 : 0);
8903  }
8904  else
8905  {
8906  arg_list_ .clear();
8907  delete_branch_.clear();
8908  return;
8909  }
8910  }
8911  }
8912  }
8913 
8915  {
8917  {
8919  }
8920 
8921  for (std::size_t i = 0; i < arg_list_.size(); ++i)
8922  {
8923  if (arg_list_[i] && delete_branch_[i])
8924  {
8925  destroy_node(arg_list_[i]);
8926  }
8927  }
8928  }
8929 
8930  inline T value() const
8931  {
8932  if (!arg_list_.empty())
8933  {
8935  }
8936 
8937  final_node_->value();
8938 
8939  return std::numeric_limits<T>::quiet_NaN();
8940  }
8941 
8942  std::string str() const
8943  {
8944  return str_base_ptr_->str();
8945  }
8946 
8947  char_cptr base() const
8948  {
8949  return str_base_ptr_->base();
8950  }
8951 
8952  std::size_t size() const
8953  {
8954  return str_base_ptr_->size();
8955  }
8956 
8958  {
8959  return str_range_ptr_->range_ref();
8960  }
8961 
8962  const range_t& range_ref() const
8963  {
8964  return str_range_ptr_->range_ref();
8965  }
8966 
8967  inline typename expression_node<T>::node_type type() const
8968  {
8970  }
8971 
8972  private:
8973 
8979  std::vector<expression_ptr> arg_list_;
8980  std::vector<unsigned char> delete_branch_;
8981  };
8982  #endif
8983 
8984  template <typename T, std::size_t N>
8985  inline T axn(T a, T x)
8986  {
8987  // a*x^n
8989  }
8990 
8991  template <typename T, std::size_t N>
8992  inline T axnb(T a, T x, T b)
8993  {
8994  // a*x^n+b
8996  }
8997 
8998  template <typename T>
8999  struct sf_base
9000  {
9007  };
9008 
9009  #define define_sfop3(NN,OP0,OP1) \
9010  template <typename T> \
9011  struct sf##NN##_op : public sf_base<T> \
9012  { \
9013  typedef typename sf_base<T>::Type Type; \
9014  static inline T process(Type x, Type y, Type z) \
9015  { \
9016  return (OP0); \
9017  } \
9018  static inline std::string id() \
9019  { \
9020  return OP1; \
9021  } \
9022  }; \
9023 
9024  define_sfop3(00,(x + y) / z ,"(t+t)/t")
9025  define_sfop3(01,(x + y) * z ,"(t+t)*t")
9026  define_sfop3(02,(x + y) - z ,"(t+t)-t")
9027  define_sfop3(03,(x + y) + z ,"(t+t)+t")
9028  define_sfop3(04,(x - y) + z ,"(t-t)+t")
9029  define_sfop3(05,(x - y) / z ,"(t-t)/t")
9030  define_sfop3(06,(x - y) * z ,"(t-t)*t")
9031  define_sfop3(07,(x * y) + z ,"(t*t)+t")
9032  define_sfop3(08,(x * y) - z ,"(t*t)-t")
9033  define_sfop3(09,(x * y) / z ,"(t*t)/t")
9034  define_sfop3(10,(x * y) * z ,"(t*t)*t")
9035  define_sfop3(11,(x / y) + z ,"(t/t)+t")
9036  define_sfop3(12,(x / y) - z ,"(t/t)-t")
9037  define_sfop3(13,(x / y) / z ,"(t/t)/t")
9038  define_sfop3(14,(x / y) * z ,"(t/t)*t")
9039  define_sfop3(15,x / (y + z) ,"t/(t+t)")
9040  define_sfop3(16,x / (y - z) ,"t/(t-t)")
9041  define_sfop3(17,x / (y * z) ,"t/(t*t)")
9042  define_sfop3(18,x / (y / z) ,"t/(t/t)")
9043  define_sfop3(19,x * (y + z) ,"t*(t+t)")
9044  define_sfop3(20,x * (y - z) ,"t*(t-t)")
9045  define_sfop3(21,x * (y * z) ,"t*(t*t)")
9046  define_sfop3(22,x * (y / z) ,"t*(t/t)")
9047  define_sfop3(23,x - (y + z) ,"t-(t+t)")
9048  define_sfop3(24,x - (y - z) ,"t-(t-t)")
9049  define_sfop3(25,x - (y / z) ,"t-(t/t)")
9050  define_sfop3(26,x - (y * z) ,"t-(t*t)")
9051  define_sfop3(27,x + (y * z) ,"t+(t*t)")
9052  define_sfop3(28,x + (y / z) ,"t+(t/t)")
9053  define_sfop3(29,x + (y + z) ,"t+(t+t)")
9054  define_sfop3(30,x + (y - z) ,"t+(t-t)")
9055  define_sfop3(31,(axnb<T,2>(x,y,z))," ")
9056  define_sfop3(32,(axnb<T,3>(x,y,z))," ")
9057  define_sfop3(33,(axnb<T,4>(x,y,z))," ")
9058  define_sfop3(34,(axnb<T,5>(x,y,z))," ")
9059  define_sfop3(35,(axnb<T,6>(x,y,z))," ")
9060  define_sfop3(36,(axnb<T,7>(x,y,z))," ")
9061  define_sfop3(37,(axnb<T,8>(x,y,z))," ")
9062  define_sfop3(38,(axnb<T,9>(x,y,z))," ")
9063  define_sfop3(39,x * numeric::log(y) + z,"")
9064  define_sfop3(40,x * numeric::log(y) - z,"")
9065  define_sfop3(41,x * numeric::log10(y) + z,"")
9066  define_sfop3(42,x * numeric::log10(y) - z,"")
9067  define_sfop3(43,x * numeric::sin(y) + z ,"")
9068  define_sfop3(44,x * numeric::sin(y) - z ,"")
9069  define_sfop3(45,x * numeric::cos(y) + z ,"")
9070  define_sfop3(46,x * numeric::cos(y) - z ,"")
9071  define_sfop3(47,details::is_true(x) ? y : z,"")
9072 
9073  #define define_sfop4(NN,OP0,OP1) \
9074  template <typename T> \
9075  struct sf##NN##_op : public sf_base<T> \
9076  { \
9077  typedef typename sf_base<T>::Type Type; \
9078  static inline T process(Type x, Type y, Type z, Type w) \
9079  { \
9080  return (OP0); \
9081  } \
9082  static inline std::string id() { return OP1; } \
9083  }; \
9084 
9085  define_sfop4(48,(x + ((y + z) / w)),"t+((t+t)/t)")
9086  define_sfop4(49,(x + ((y + z) * w)),"t+((t+t)*t)")
9087  define_sfop4(50,(x + ((y - z) / w)),"t+((t-t)/t)")
9088  define_sfop4(51,(x + ((y - z) * w)),"t+((t-t)*t)")
9089  define_sfop4(52,(x + ((y * z) / w)),"t+((t*t)/t)")
9090  define_sfop4(53,(x + ((y * z) * w)),"t+((t*t)*t)")
9091  define_sfop4(54,(x + ((y / z) + w)),"t+((t/t)+t)")
9092  define_sfop4(55,(x + ((y / z) / w)),"t+((t/t)/t)")
9093  define_sfop4(56,(x + ((y / z) * w)),"t+((t/t)*t)")
9094  define_sfop4(57,(x - ((y + z) / w)),"t-((t+t)/t)")
9095  define_sfop4(58,(x - ((y + z) * w)),"t-((t+t)*t)")
9096  define_sfop4(59,(x - ((y - z) / w)),"t-((t-t)/t)")
9097  define_sfop4(60,(x - ((y - z) * w)),"t-((t-t)*t)")
9098  define_sfop4(61,(x - ((y * z) / w)),"t-((t*t)/t)")
9099  define_sfop4(62,(x - ((y * z) * w)),"t-((t*t)*t)")
9100  define_sfop4(63,(x - ((y / z) / w)),"t-((t/t)/t)")
9101  define_sfop4(64,(x - ((y / z) * w)),"t-((t/t)*t)")
9102  define_sfop4(65,(((x + y) * z) - w),"((t+t)*t)-t")
9103  define_sfop4(66,(((x - y) * z) - w),"((t-t)*t)-t")
9104  define_sfop4(67,(((x * y) * z) - w),"((t*t)*t)-t")
9105  define_sfop4(68,(((x / y) * z) - w),"((t/t)*t)-t")
9106  define_sfop4(69,(((x + y) / z) - w),"((t+t)/t)-t")
9107  define_sfop4(70,(((x - y) / z) - w),"((t-t)/t)-t")
9108  define_sfop4(71,(((x * y) / z) - w),"((t*t)/t)-t")
9109  define_sfop4(72,(((x / y) / z) - w),"((t/t)/t)-t")
9110  define_sfop4(73,((x * y) + (z * w)),"(t*t)+(t*t)")
9111  define_sfop4(74,((x * y) - (z * w)),"(t*t)-(t*t)")
9112  define_sfop4(75,((x * y) + (z / w)),"(t*t)+(t/t)")
9113  define_sfop4(76,((x * y) - (z / w)),"(t*t)-(t/t)")
9114  define_sfop4(77,((x / y) + (z / w)),"(t/t)+(t/t)")
9115  define_sfop4(78,((x / y) - (z / w)),"(t/t)-(t/t)")
9116  define_sfop4(79,((x / y) - (z * w)),"(t/t)-(t*t)")
9117  define_sfop4(80,(x / (y + (z * w))),"t/(t+(t*t))")
9118  define_sfop4(81,(x / (y - (z * w))),"t/(t-(t*t))")
9119  define_sfop4(82,(x * (y + (z * w))),"t*(t+(t*t))")
9120  define_sfop4(83,(x * (y - (z * w))),"t*(t-(t*t))")
9121 
9122  define_sfop4(84,(axn<T,2>(x,y) + axn<T,2>(z,w)),"")
9123  define_sfop4(85,(axn<T,3>(x,y) + axn<T,3>(z,w)),"")
9124  define_sfop4(86,(axn<T,4>(x,y) + axn<T,4>(z,w)),"")
9125  define_sfop4(87,(axn<T,5>(x,y) + axn<T,5>(z,w)),"")
9126  define_sfop4(88,(axn<T,6>(x,y) + axn<T,6>(z,w)),"")
9127  define_sfop4(89,(axn<T,7>(x,y) + axn<T,7>(z,w)),"")
9128  define_sfop4(90,(axn<T,8>(x,y) + axn<T,8>(z,w)),"")
9129  define_sfop4(91,(axn<T,9>(x,y) + axn<T,9>(z,w)),"")
9130  define_sfop4(92,((details::is_true(x) && details::is_true(y)) ? z : w),"")
9131  define_sfop4(93,((details::is_true(x) || details::is_true(y)) ? z : w),"")
9132  define_sfop4(94,((x < y) ? z : w),"")
9133  define_sfop4(95,((x <= y) ? z : w),"")
9134  define_sfop4(96,((x > y) ? z : w),"")
9135  define_sfop4(97,((x >= y) ? z : w),"")
9136  define_sfop4(98,(details::is_true(numeric::equal(x,y)) ? z : w),"")
9137  define_sfop4(99,(x * numeric::sin(y) + z * numeric::cos(w)),"")
9138 
9139  define_sfop4(ext00,((x + y) - (z * w)),"(t+t)-(t*t)")
9140  define_sfop4(ext01,((x + y) - (z / w)),"(t+t)-(t/t)")
9141  define_sfop4(ext02,((x + y) + (z * w)),"(t+t)+(t*t)")
9142  define_sfop4(ext03,((x + y) + (z / w)),"(t+t)+(t/t)")
9143  define_sfop4(ext04,((x - y) + (z * w)),"(t-t)+(t*t)")
9144  define_sfop4(ext05,((x - y) + (z / w)),"(t-t)+(t/t)")
9145  define_sfop4(ext06,((x - y) - (z * w)),"(t-t)-(t*t)")
9146  define_sfop4(ext07,((x - y) - (z / w)),"(t-t)-(t/t)")
9147  define_sfop4(ext08,((x + y) - (z - w)),"(t+t)-(t-t)")
9148  define_sfop4(ext09,((x + y) + (z - w)),"(t+t)+(t-t)")
9149  define_sfop4(ext10,((x + y) + (z + w)),"(t+t)+(t+t)")
9150  define_sfop4(ext11,((x + y) * (z - w)),"(t+t)*(t-t)")
9151  define_sfop4(ext12,((x + y) / (z - w)),"(t+t)/(t-t)")
9152  define_sfop4(ext13,((x - y) - (z + w)),"(t-t)-(t+t)")
9153  define_sfop4(ext14,((x - y) + (z + w)),"(t-t)+(t+t)")
9154  define_sfop4(ext15,((x - y) * (z + w)),"(t-t)*(t+t)")
9155  define_sfop4(ext16,((x - y) / (z + w)),"(t-t)/(t+t)")
9156  define_sfop4(ext17,((x * y) - (z + w)),"(t*t)-(t+t)")
9157  define_sfop4(ext18,((x / y) - (z + w)),"(t/t)-(t+t)")
9158  define_sfop4(ext19,((x * y) + (z + w)),"(t*t)+(t+t)")
9159  define_sfop4(ext20,((x / y) + (z + w)),"(t/t)+(t+t)")
9160  define_sfop4(ext21,((x * y) + (z - w)),"(t*t)+(t-t)")
9161  define_sfop4(ext22,((x / y) + (z - w)),"(t/t)+(t-t)")
9162  define_sfop4(ext23,((x * y) - (z - w)),"(t*t)-(t-t)")
9163  define_sfop4(ext24,((x / y) - (z - w)),"(t/t)-(t-t)")
9164  define_sfop4(ext25,((x + y) * (z * w)),"(t+t)*(t*t)")
9165  define_sfop4(ext26,((x + y) * (z / w)),"(t+t)*(t/t)")
9166  define_sfop4(ext27,((x + y) / (z * w)),"(t+t)/(t*t)")
9167  define_sfop4(ext28,((x + y) / (z / w)),"(t+t)/(t/t)")
9168  define_sfop4(ext29,((x - y) / (z * w)),"(t-t)/(t*t)")
9169  define_sfop4(ext30,((x - y) / (z / w)),"(t-t)/(t/t)")
9170  define_sfop4(ext31,((x - y) * (z * w)),"(t-t)*(t*t)")
9171  define_sfop4(ext32,((x - y) * (z / w)),"(t-t)*(t/t)")
9172  define_sfop4(ext33,((x * y) * (z + w)),"(t*t)*(t+t)")
9173  define_sfop4(ext34,((x / y) * (z + w)),"(t/t)*(t+t)")
9174  define_sfop4(ext35,((x * y) / (z + w)),"(t*t)/(t+t)")
9175  define_sfop4(ext36,((x / y) / (z + w)),"(t/t)/(t+t)")
9176  define_sfop4(ext37,((x * y) / (z - w)),"(t*t)/(t-t)")
9177  define_sfop4(ext38,((x / y) / (z - w)),"(t/t)/(t-t)")
9178  define_sfop4(ext39,((x * y) * (z - w)),"(t*t)*(t-t)")
9179  define_sfop4(ext40,((x * y) / (z * w)),"(t*t)/(t*t)")
9180  define_sfop4(ext41,((x / y) * (z / w)),"(t/t)*(t/t)")
9181  define_sfop4(ext42,((x / y) * (z - w)),"(t/t)*(t-t)")
9182  define_sfop4(ext43,((x * y) * (z * w)),"(t*t)*(t*t)")
9183  define_sfop4(ext44,(x + (y * (z / w))),"t+(t*(t/t))")
9184  define_sfop4(ext45,(x - (y * (z / w))),"t-(t*(t/t))")
9185  define_sfop4(ext46,(x + (y / (z * w))),"t+(t/(t*t))")
9186  define_sfop4(ext47,(x - (y / (z * w))),"t-(t/(t*t))")
9187  define_sfop4(ext48,(((x - y) - z) * w),"((t-t)-t)*t")
9188  define_sfop4(ext49,(((x - y) - z) / w),"((t-t)-t)/t")
9189  define_sfop4(ext50,(((x - y) + z) * w),"((t-t)+t)*t")
9190  define_sfop4(ext51,(((x - y) + z) / w),"((t-t)+t)/t")
9191  define_sfop4(ext52,((x + (y - z)) * w),"(t+(t-t))*t")
9192  define_sfop4(ext53,((x + (y - z)) / w),"(t+(t-t))/t")
9193  define_sfop4(ext54,((x + y) / (z + w)),"(t+t)/(t+t)")
9194  define_sfop4(ext55,((x - y) / (z - w)),"(t-t)/(t-t)")
9195  define_sfop4(ext56,((x + y) * (z + w)),"(t+t)*(t+t)")
9196  define_sfop4(ext57,((x - y) * (z - w)),"(t-t)*(t-t)")
9197  define_sfop4(ext58,((x - y) + (z - w)),"(t-t)+(t-t)")
9198  define_sfop4(ext59,((x - y) - (z - w)),"(t-t)-(t-t)")
9199  define_sfop4(ext60,((x / y) + (z * w)),"(t/t)+(t*t)")
9200  define_sfop4(ext61,(((x * y) * z) / w),"((t*t)*t)/t")
9201 
9202  #undef define_sfop3
9203  #undef define_sfop4
9204 
9205  template <typename T, typename SpecialFunction>
9206  class sf3_node : public trinary_node<T>
9207  {
9208  public:
9209 
9210  typedef expression_node<T>* expression_ptr;
9211 
9212  sf3_node(const operator_type& opr,
9213  expression_ptr branch0,
9214  expression_ptr branch1,
9215  expression_ptr branch2)
9216  : trinary_node<T>(opr, branch0, branch1, branch2)
9217  {}
9218 
9219  inline T value() const
9220  {
9221  const T x = trinary_node<T>::branch_[0].first->value();
9222  const T y = trinary_node<T>::branch_[1].first->value();
9223  const T z = trinary_node<T>::branch_[2].first->value();
9224 
9225  return SpecialFunction::process(x, y, z);
9226  }
9227  };
9228 
9229  template <typename T, typename SpecialFunction>
9230  class sf4_node : public quaternary_node<T>
9231  {
9232  public:
9233 
9235 
9237  expression_ptr branch0,
9238  expression_ptr branch1,
9239  expression_ptr branch2,
9240  expression_ptr branch3)
9241  : quaternary_node<T>(opr, branch0, branch1, branch2, branch3)
9242  {}
9243 
9244  inline T value() const
9245  {
9246  const T x = quaternary_node<T>::branch_[0].first->value();
9247  const T y = quaternary_node<T>::branch_[1].first->value();
9248  const T z = quaternary_node<T>::branch_[2].first->value();
9249  const T w = quaternary_node<T>::branch_[3].first->value();
9250 
9251  return SpecialFunction::process(x, y, z, w);
9252  }
9253  };
9254 
9255  template <typename T, typename SpecialFunction>
9256  class sf3_var_node : public expression_node<T>
9257  {
9258  public:
9259 
9261 
9262  sf3_var_node(const T& v0, const T& v1, const T& v2)
9263  : v0_(v0),
9264  v1_(v1),
9265  v2_(v2)
9266  {}
9267 
9268  inline T value() const
9269  {
9270  return SpecialFunction::process(v0_, v1_, v2_);
9271  }
9272 
9273  inline typename expression_node<T>::node_type type() const
9274  {
9276  }
9277 
9278  private:
9279 
9282 
9283  const T& v0_;
9284  const T& v1_;
9285  const T& v2_;
9286  };
9287 
9288  template <typename T, typename SpecialFunction>
9289  class sf4_var_node : public expression_node<T>
9290  {
9291  public:
9292 
9294 
9295  sf4_var_node(const T& v0, const T& v1, const T& v2, const T& v3)
9296  : v0_(v0),
9297  v1_(v1),
9298  v2_(v2),
9299  v3_(v3)
9300  {}
9301 
9302  inline T value() const
9303  {
9304  return SpecialFunction::process(v0_, v1_, v2_, v3_);
9305  }
9306 
9307  inline typename expression_node<T>::node_type type() const
9308  {
9310  }
9311 
9312  private:
9313 
9316 
9317  const T& v0_;
9318  const T& v1_;
9319  const T& v2_;
9320  const T& v3_;
9321  };
9322 
9323  template <typename T, typename VarArgFunction>
9324  class vararg_node : public expression_node<T>
9325  {
9326  public:
9327 
9329 
9330  template <typename Allocator,
9331  template <typename,typename> class Sequence>
9332  vararg_node(const Sequence<expression_ptr,Allocator>& arg_list)
9333  {
9334  arg_list_ .resize(arg_list.size());
9335  delete_branch_.resize(arg_list.size());
9336 
9337  for (std::size_t i = 0; i < arg_list.size(); ++i)
9338  {
9339  if (arg_list[i])
9340  {
9341  arg_list_[i] = arg_list[i];
9342  delete_branch_[i] = static_cast<unsigned char>(branch_deletable(arg_list_[i]) ? 1 : 0);
9343  }
9344  else
9345  {
9346  arg_list_.clear();
9347  delete_branch_.clear();
9348  return;
9349  }
9350  }
9351  }
9352 
9354  {
9355  for (std::size_t i = 0; i < arg_list_.size(); ++i)
9356  {
9357  if (arg_list_[i] && delete_branch_[i])
9358  {
9359  destroy_node(arg_list_[i]);
9360  }
9361  }
9362  }
9363 
9364  inline T value() const
9365  {
9366  if (!arg_list_.empty())
9368  else
9369  return std::numeric_limits<T>::quiet_NaN();
9370  }
9371 
9372  inline typename expression_node<T>::node_type type() const
9373  {
9375  }
9376 
9377  private:
9378 
9379  std::vector<expression_ptr> arg_list_;
9380  std::vector<unsigned char> delete_branch_;
9381  };
9382 
9383  template <typename T, typename VarArgFunction>
9385  {
9386  public:
9387 
9389 
9390  template <typename Allocator,
9391  template <typename,typename> class Sequence>
9392  vararg_varnode(const Sequence<expression_ptr,Allocator>& arg_list)
9393  {
9394  arg_list_.resize(arg_list.size());
9395 
9396  for (std::size_t i = 0; i < arg_list.size(); ++i)
9397  {
9398  if (arg_list[i] && is_variable_node(arg_list[i]))
9399  {
9400  variable_node<T>* var_node_ptr = static_cast<variable_node<T>*>(arg_list[i]);
9401  arg_list_[i] = (&var_node_ptr->ref());
9402  }
9403  else
9404  {
9405  arg_list_.clear();
9406  return;
9407  }
9408  }
9409  }
9410 
9411  inline T value() const
9412  {
9413  if (!arg_list_.empty())
9415  else
9416  return std::numeric_limits<T>::quiet_NaN();
9417  }
9418 
9419  inline typename expression_node<T>::node_type type() const
9420  {
9422  }
9423 
9424  private:
9425 
9426  std::vector<const T*> arg_list_;
9427  };
9428 
9429  template <typename T, typename VecFunction>
9431  {
9432  public:
9433 
9435 
9437  : ivec_ptr_(0),
9438  v_(v),
9440  {
9441  if (is_ivector_node(v))
9442  {
9443  ivec_ptr_ = dynamic_cast<vector_interface<T>*>(v);
9444  }
9445  else
9446  ivec_ptr_ = 0;
9447  }
9448 
9450  {
9451  if (v_ && v_deletable_)
9452  {
9453  destroy_node(v_);
9454  }
9455  }
9456 
9457  inline T value() const
9458  {
9459  if (ivec_ptr_)
9460  {
9461  v_->value();
9463  }
9464  else
9465  return std::numeric_limits<T>::quiet_NaN();
9466  }
9467 
9468  inline typename expression_node<T>::node_type type() const
9469  {
9471  }
9472 
9473  private:
9474 
9477  const bool v_deletable_;
9478  };
9479 
9480  template <typename T>
9481  class assignment_node : public binary_node<T>
9482  {
9483  public:
9484 
9486 
9488  expression_ptr branch0,
9489  expression_ptr branch1)
9490  : binary_node<T>(opr, branch0, branch1),
9491  var_node_ptr_(0)
9492  {
9494  {
9495  var_node_ptr_ = static_cast<variable_node<T>*>(binary_node<T>::branch_[0].first);
9496  }
9497  }
9498 
9499  inline T value() const
9500  {
9501  if (var_node_ptr_)
9502  {
9503  T& result = var_node_ptr_->ref();
9504 
9505  result = binary_node<T>::branch_[1].first->value();
9506 
9507  return result;
9508  }
9509  else
9510  return std::numeric_limits<T>::quiet_NaN();
9511  }
9512 
9513  private:
9514 
9516  };
9517 
9518  template <typename T>
9520  {
9521  public:
9522 
9524 
9526  expression_ptr branch0,
9527  expression_ptr branch1)
9528  : binary_node<T>(opr, branch0, branch1),
9529  vec_node_ptr_(0)
9530  {
9532  {
9533  vec_node_ptr_ = static_cast<vector_elem_node<T>*>(binary_node<T>::branch_[0].first);
9534  }
9535  }
9536 
9537  inline T value() const
9538  {
9539  if (vec_node_ptr_)
9540  {
9541  T& result = vec_node_ptr_->ref();
9542 
9543  result = binary_node<T>::branch_[1].first->value();
9544 
9545  return result;
9546  }
9547  else
9548  return std::numeric_limits<T>::quiet_NaN();
9549  }
9550 
9551  private:
9552 
9554  };
9555 
9556  template <typename T>
9558  {
9559  public:
9560 
9562 
9564  expression_ptr branch0,
9565  expression_ptr branch1)
9566  : binary_node<T>(opr, branch0, branch1),
9567  rbvec_node_ptr_(0)
9568  {
9570  {
9572  }
9573  }
9574 
9575  inline T value() const
9576  {
9577  if (rbvec_node_ptr_)
9578  {
9579  T& result = rbvec_node_ptr_->ref();
9580 
9581  result = binary_node<T>::branch_[1].first->value();
9582 
9583  return result;
9584  }
9585  else
9586  return std::numeric_limits<T>::quiet_NaN();
9587  }
9588 
9589  private:
9590 
9592  };
9593 
9594  template <typename T>
9596  {
9597  public:
9598 
9600 
9602  expression_ptr branch0,
9603  expression_ptr branch1)
9604  : binary_node<T>(opr, branch0, branch1),
9605  rbvec_node_ptr_(0)
9606  {
9608  {
9610  }
9611  }
9612 
9613  inline T value() const
9614  {
9615  if (rbvec_node_ptr_)
9616  {
9617  T& result = rbvec_node_ptr_->ref();
9618 
9619  result = binary_node<T>::branch_[1].first->value();
9620 
9621  return result;
9622  }
9623  else
9624  return std::numeric_limits<T>::quiet_NaN();
9625  }
9626 
9627  private:
9628 
9630  };
9631 
9632  template <typename T>
9633  class assignment_vec_node : public binary_node <T>,
9634  public vector_interface<T>
9635  {
9636  public:
9637 
9641 
9643  expression_ptr branch0,
9644  expression_ptr branch1)
9645  : binary_node<T>(opr, branch0, branch1),
9646  vec_node_ptr_(0)
9647  {
9649  {
9650  vec_node_ptr_ = static_cast<vector_node<T>*>(binary_node<T>::branch_[0].first);
9651  vds() = vec_node_ptr_->vds();
9652  }
9653  }
9654 
9655  inline T value() const
9656  {
9657  if (vec_node_ptr_)
9658  {
9659  const T v = binary_node<T>::branch_[1].first->value();
9660 
9661  T* vec = vds().data();
9662 
9663  loop_unroll::details lud(size());
9664  const T* upper_bound = vec + lud.upper_bound;
9665 
9666  while (vec < upper_bound)
9667  {
9668  #define exprtk_loop(N) \
9669  vec[N] = v; \
9670 
9671  exprtk_loop( 0) exprtk_loop( 1)
9672  exprtk_loop( 2) exprtk_loop( 3)
9673  #ifndef exprtk_disable_superscalar_unroll
9674  exprtk_loop( 4) exprtk_loop( 5)
9675  exprtk_loop( 6) exprtk_loop( 7)
9676  exprtk_loop( 8) exprtk_loop( 9)
9677  exprtk_loop(10) exprtk_loop(11)
9678  exprtk_loop(12) exprtk_loop(13)
9679  exprtk_loop(14) exprtk_loop(15)
9680  #endif
9681 
9682  vec += lud.batch_size;
9683  }
9684 
9686  switch (lud.remainder)
9687  {
9688  #define case_stmt(N) \
9689  case N : *vec++ = v; \
9690 
9691  #ifndef exprtk_disable_superscalar_unroll
9692  case_stmt(15) case_stmt(14)
9693  case_stmt(13) case_stmt(12)
9694  case_stmt(11) case_stmt(10)
9695  case_stmt( 9) case_stmt( 8)
9696  case_stmt( 7) case_stmt( 6)
9697  case_stmt( 5) case_stmt( 4)
9698  #endif
9699  case_stmt( 3) case_stmt( 2)
9700  case_stmt( 1)
9701  }
9703 
9704  #undef exprtk_loop
9705  #undef case_stmt
9706 
9707  return vec_node_ptr_->value();
9708  }
9709  else
9710  return std::numeric_limits<T>::quiet_NaN();
9711  }
9712 
9714  {
9715  return vec_node_ptr_;
9716  }
9717 
9719  {
9720  return vec_node_ptr_;
9721  }
9722 
9723  inline typename expression_node<T>::node_type type() const
9724  {
9726  }
9727 
9728  std::size_t size() const
9729  {
9730  return vds().size();
9731  }
9732 
9734  {
9735  return vds_;
9736  }
9737 
9738  const vds_t& vds() const
9739  {
9740  return vds_;
9741  }
9742 
9743  private:
9744 
9747  };
9748 
9749  template <typename T>
9751  public vector_interface<T>
9752  {
9753  public:
9754 
9758 
9760  expression_ptr branch0,
9761  expression_ptr branch1)
9762  : binary_node<T>(opr, branch0, branch1),
9763  vec0_node_ptr_(0),
9764  vec1_node_ptr_(0),
9765  initialised_(false),
9766  src_is_ivec_(false)
9767  {
9769  {
9770  vec0_node_ptr_ = static_cast<vector_node<T>*>(binary_node<T>::branch_[0].first);
9771  vds() = vec0_node_ptr_->vds();
9772  }
9773 
9775  {
9776  vec1_node_ptr_ = static_cast<vector_node<T>*>(binary_node<T>::branch_[1].first);
9778  }
9779  else if (is_ivector_node(binary_node<T>::branch_[1].first))
9780  {
9781  vector_interface<T>* vi = reinterpret_cast<vector_interface<T>*>(0);
9782 
9783  if (0 != (vi = dynamic_cast<vector_interface<T>*>(binary_node<T>::branch_[1].first)))
9784  {
9785  vec1_node_ptr_ = vi->vec();
9786 
9787  if (!vi->side_effect())
9788  {
9789  vi->vds() = vds();
9790  src_is_ivec_ = true;
9791  }
9792  else
9793  vds_t::match_sizes(vds(),vi->vds());
9794  }
9795  }
9796 
9798  }
9799 
9800  inline T value() const
9801  {
9802  if (initialised_)
9803  {
9804  binary_node<T>::branch_[1].first->value();
9805 
9806  if (src_is_ivec_)
9807  return vec0_node_ptr_->value();
9808 
9809  T* vec0 = vec0_node_ptr_->vds().data();
9810  T* vec1 = vec1_node_ptr_->vds().data();
9811 
9812  loop_unroll::details lud(size());
9813  const T* upper_bound = vec0 + lud.upper_bound;
9814 
9815  while (vec0 < upper_bound)
9816  {
9817  #define exprtk_loop(N) \
9818  vec0[N] = vec1[N]; \
9819 
9820  exprtk_loop( 0) exprtk_loop( 1)
9821  exprtk_loop( 2) exprtk_loop( 3)
9822  #ifndef exprtk_disable_superscalar_unroll
9823  exprtk_loop( 4) exprtk_loop( 5)
9824  exprtk_loop( 6) exprtk_loop( 7)
9825  exprtk_loop( 8) exprtk_loop( 9)
9826  exprtk_loop(10) exprtk_loop(11)
9827  exprtk_loop(12) exprtk_loop(13)
9828  exprtk_loop(14) exprtk_loop(15)
9829  #endif
9830 
9831  vec0 += lud.batch_size;
9832  vec1 += lud.batch_size;
9833  }
9834 
9836  switch (lud.remainder)
9837  {
9838  #define case_stmt(N) \
9839  case N : *vec0++ = *vec1++; \
9840 
9841  #ifndef exprtk_disable_superscalar_unroll
9842  case_stmt(15) case_stmt(14)
9843  case_stmt(13) case_stmt(12)
9844  case_stmt(11) case_stmt(10)
9845  case_stmt( 9) case_stmt( 8)
9846  case_stmt( 7) case_stmt( 6)
9847  case_stmt( 5) case_stmt( 4)
9848  #endif
9849  case_stmt( 3) case_stmt( 2)
9850  case_stmt( 1)
9851  }
9853 
9854  #undef exprtk_loop
9855  #undef case_stmt
9856 
9857  return vec0_node_ptr_->value();
9858  }
9859  else
9860  return std::numeric_limits<T>::quiet_NaN();
9861  }
9862 
9864  {
9865  return vec0_node_ptr_;
9866  }
9867 
9869  {
9870  return vec0_node_ptr_;
9871  }
9872 
9873  inline typename expression_node<T>::node_type type() const
9874  {
9876  }
9877 
9878  std::size_t size() const
9879  {
9880  return vds().size();
9881  }
9882 
9884  {
9885  return vds_;
9886  }
9887 
9888  const vds_t& vds() const
9889  {
9890  return vds_;
9891  }
9892 
9893  private:
9894 
9900  };
9901 
9902  template <typename T, typename Operation>
9904  {
9905  public:
9906 
9908 
9910  expression_ptr branch0,
9911  expression_ptr branch1)
9912  : binary_node<T>(opr, branch0, branch1),
9913  var_node_ptr_(0)
9914  {
9916  {
9917  var_node_ptr_ = static_cast<variable_node<T>*>(binary_node<T>::branch_[0].first);
9918  }
9919  }
9920 
9921  inline T value() const
9922  {
9923  if (var_node_ptr_)
9924  {
9925  T& v = var_node_ptr_->ref();
9927 
9928  return v;
9929  }
9930  else
9931  return std::numeric_limits<T>::quiet_NaN();
9932  }
9933 
9934  private:
9935 
9937  };
9938 
9939  template <typename T, typename Operation>
9941  {
9942  public:
9943 
9945 
9947  expression_ptr branch0,
9948  expression_ptr branch1)
9949  : binary_node<T>(opr, branch0, branch1),
9950  vec_node_ptr_(0)
9951  {
9953  {
9954  vec_node_ptr_ = static_cast<vector_elem_node<T>*>(binary_node<T>::branch_[0].first);
9955  }
9956  }
9957 
9958  inline T value() const
9959  {
9960  if (vec_node_ptr_)
9961  {
9962  T& v = vec_node_ptr_->ref();
9964 
9965  return v;
9966  }
9967  else
9968  return std::numeric_limits<T>::quiet_NaN();
9969  }
9970 
9971  private:
9972 
9974  };
9975 
9976  template <typename T, typename Operation>
9978  {
9979  public:
9980 
9982 
9984  expression_ptr branch0,
9985  expression_ptr branch1)
9986  : binary_node<T>(opr, branch0, branch1),
9987  rbvec_node_ptr_(0)
9988  {
9990  {
9992  }
9993  }
9994 
9995  inline T value() const
9996  {
9997  if (rbvec_node_ptr_)
9998  {
9999  T& v = rbvec_node_ptr_->ref();
10001 
10002  return v;
10003  }
10004  else
10005  return std::numeric_limits<T>::quiet_NaN();
10006  }
10007 
10008  private:
10009 
10011  };
10012 
10013  template <typename T, typename Operation>
10015  {
10016  public:
10017 
10019 
10021  expression_ptr branch0,
10022  expression_ptr branch1)
10023  : binary_node<T>(opr, branch0, branch1),
10024  rbvec_node_ptr_(0)
10025  {
10027  {
10029  }
10030  }
10031 
10032  inline T value() const
10033  {
10034  if (rbvec_node_ptr_)
10035  {
10036  T& v = rbvec_node_ptr_->ref();
10038 
10039  return v;
10040  }
10041  else
10042  return std::numeric_limits<T>::quiet_NaN();
10043  }
10044 
10045  private:
10046 
10048  };
10049 
10050  template <typename T, typename Operation>
10052  public vector_interface<T>
10053  {
10054  public:
10055 
10059 
10061  expression_ptr branch0,
10062  expression_ptr branch1)
10063  : binary_node<T>(opr, branch0, branch1),
10064  vec_node_ptr_(0)
10065  {
10067  {
10068  vec_node_ptr_ = static_cast<vector_node<T>*>(binary_node<T>::branch_[0].first);
10069  vds() = vec_node_ptr_->vds();
10070  }
10071  }
10072 
10073  inline T value() const
10074  {
10075  if (vec_node_ptr_)
10076  {
10077  const T v = binary_node<T>::branch_[1].first->value();
10078 
10079  T* vec = vds().data();
10080 
10081  loop_unroll::details lud(size());
10082  const T* upper_bound = vec + lud.upper_bound;
10083 
10084  while (vec < upper_bound)
10085  {
10086  #define exprtk_loop(N) \
10087  Operation::assign(vec[N],v); \
10088 
10089  exprtk_loop( 0) exprtk_loop( 1)
10090  exprtk_loop( 2) exprtk_loop( 3)
10091  #ifndef exprtk_disable_superscalar_unroll
10092  exprtk_loop( 4) exprtk_loop( 5)
10093  exprtk_loop( 6) exprtk_loop( 7)
10094  exprtk_loop( 8) exprtk_loop( 9)
10095  exprtk_loop(10) exprtk_loop(11)
10096  exprtk_loop(12) exprtk_loop(13)
10097  exprtk_loop(14) exprtk_loop(15)
10098  #endif
10099 
10100  vec += lud.batch_size;
10101  }
10102 
10104  switch (lud.remainder)
10105  {
10106  #define case_stmt(N) \
10107  case N : Operation::assign(*vec++,v); \
10108 
10109  #ifndef exprtk_disable_superscalar_unroll
10110  case_stmt(15) case_stmt(14)
10111  case_stmt(13) case_stmt(12)
10112  case_stmt(11) case_stmt(10)
10113  case_stmt( 9) case_stmt( 8)
10114  case_stmt( 7) case_stmt( 6)
10115  case_stmt( 5) case_stmt( 4)
10116  #endif
10117  case_stmt( 3) case_stmt( 2)
10118  case_stmt( 1)
10119  }
10121 
10122 
10123  #undef exprtk_loop
10124  #undef case_stmt
10125 
10126  return vec_node_ptr_->value();
10127  }
10128  else
10129  return std::numeric_limits<T>::quiet_NaN();
10130  }
10131 
10133  {
10134  return vec_node_ptr_;
10135  }
10136 
10138  {
10139  return vec_node_ptr_;
10140  }
10141 
10142  inline typename expression_node<T>::node_type type() const
10143  {
10145  }
10146 
10147  std::size_t size() const
10148  {
10149  return vds().size();
10150  }
10151 
10153  {
10154  return vds_;
10155  }
10156 
10157  const vds_t& vds() const
10158  {
10159  return vds_;
10160  }
10161 
10162  bool side_effect() const
10163  {
10164  return true;
10165  }
10166 
10167  private:
10168 
10171  };
10172 
10173  template <typename T, typename Operation>
10175  public vector_interface<T>
10176  {
10177  public:
10178 
10182 
10184  expression_ptr branch0,
10185  expression_ptr branch1)
10186  : binary_node<T>(opr, branch0, branch1),
10187  vec0_node_ptr_(0),
10188  vec1_node_ptr_(0),
10189  initialised_(false)
10190  {
10192  {
10193  vec0_node_ptr_ = static_cast<vector_node<T>*>(binary_node<T>::branch_[0].first);
10194  vds() = vec0_node_ptr_->vds();
10195  }
10196 
10198  {
10199  vec1_node_ptr_ = static_cast<vector_node<T>*>(binary_node<T>::branch_[1].first);
10200  vec1_node_ptr_->vds() = vds();
10201  }
10202  else if (is_ivector_node(binary_node<T>::branch_[1].first))
10203  {
10204  vector_interface<T>* vi = reinterpret_cast<vector_interface<T>*>(0);
10205 
10206  if (0 != (vi = dynamic_cast<vector_interface<T>*>(binary_node<T>::branch_[1].first)))
10207  {
10208  vec1_node_ptr_ = vi->vec();
10209  vec1_node_ptr_->vds() = vds();
10210  }
10211  else
10213  }
10214 
10216  }
10217 
10218  inline T value() const
10219  {
10220  if (initialised_)
10221  {
10222  binary_node<T>::branch_[0].first->value();
10223  binary_node<T>::branch_[1].first->value();
10224 
10225  T* vec0 = vec0_node_ptr_->vds().data();
10226  T* vec1 = vec1_node_ptr_->vds().data();
10227 
10228  loop_unroll::details lud(size());
10229  const T* upper_bound = vec0 + lud.upper_bound;
10230 
10231  while (vec0 < upper_bound)
10232  {
10233  #define exprtk_loop(N) \
10234  vec0[N] = Operation::process(vec0[N],vec1[N]); \
10235 
10236  exprtk_loop( 0) exprtk_loop( 1)
10237  exprtk_loop( 2) exprtk_loop( 3)
10238  #ifndef exprtk_disable_superscalar_unroll
10239  exprtk_loop( 4) exprtk_loop( 5)
10240  exprtk_loop( 6) exprtk_loop( 7)
10241  exprtk_loop( 8) exprtk_loop( 9)
10242  exprtk_loop(10) exprtk_loop(11)
10243  exprtk_loop(12) exprtk_loop(13)
10244  exprtk_loop(14) exprtk_loop(15)
10245  #endif
10246 
10247  vec0 += lud.batch_size;
10248  vec1 += lud.batch_size;
10249  }
10250 
10251  int i = 0;
10252 
10254  switch (lud.remainder)
10255  {
10256  #define case_stmt(N) \
10257  case N : { vec0[i] = Operation::process(vec0[i],vec1[i]); ++i; } \
10258 
10259  #ifndef exprtk_disable_superscalar_unroll
10260  case_stmt(15) case_stmt(14)
10261  case_stmt(13) case_stmt(12)
10262  case_stmt(11) case_stmt(10)
10263  case_stmt( 9) case_stmt( 8)
10264  case_stmt( 7) case_stmt( 6)
10265  case_stmt( 5) case_stmt( 4)
10266  #endif
10267  case_stmt( 3) case_stmt( 2)
10268  case_stmt( 1)
10269  }
10271 
10272  #undef exprtk_loop
10273  #undef case_stmt
10274 
10275  return vec0_node_ptr_->value();
10276  }
10277  else
10278  return std::numeric_limits<T>::quiet_NaN();
10279  }
10280 
10282  {
10283  return vec0_node_ptr_;
10284  }
10285 
10287  {
10288  return vec0_node_ptr_;
10289  }
10290 
10291  inline typename expression_node<T>::node_type type() const
10292  {
10294  }
10295 
10296  std::size_t size() const
10297  {
10298  return vds().size();
10299  }
10300 
10302  {
10303  return vds_;
10304  }
10305 
10306  const vds_t& vds() const
10307  {
10308  return vds_;
10309  }
10310 
10311  bool side_effect() const
10312  {
10313  return true;
10314  }
10315 
10316  private:
10317 
10322  };
10323 
10324  template <typename T, typename Operation>
10326  public vector_interface<T>
10327  {
10328  public:
10329 
10334 
10336  expression_ptr branch0,
10337  expression_ptr branch1)
10338  : binary_node<T>(opr, branch0, branch1),
10339  vec0_node_ptr_(0),
10340  vec1_node_ptr_(0),
10341  temp_ (0),
10342  temp_vec_node_(0),
10343  initialised_(false)
10344  {
10345  bool v0_is_ivec = false;
10346  bool v1_is_ivec = false;
10347 
10349  {
10350  vec0_node_ptr_ = static_cast<vector_node_ptr>(binary_node<T>::branch_[0].first);
10351  }
10352  else if (is_ivector_node(binary_node<T>::branch_[0].first))
10353  {
10354  vector_interface<T>* vi = reinterpret_cast<vector_interface<T>*>(0);
10355 
10356  if (0 != (vi = dynamic_cast<vector_interface<T>*>(binary_node<T>::branch_[0].first)))
10357  {
10358  vec0_node_ptr_ = vi->vec();
10359  v0_is_ivec = true;
10360  }
10361  }
10362 
10364  {
10365  vec1_node_ptr_ = static_cast<vector_node_ptr>(binary_node<T>::branch_[1].first);
10366  }
10367  else if (is_ivector_node(binary_node<T>::branch_[1].first))
10368  {
10369  vector_interface<T>* vi = reinterpret_cast<vector_interface<T>*>(0);
10370 
10371  if (0 != (vi = dynamic_cast<vector_interface<T>*>(binary_node<T>::branch_[1].first)))
10372  {
10373  vec1_node_ptr_ = vi->vec();
10374  v1_is_ivec = true;
10375  }
10376  }
10377 
10379  {
10382 
10383  if (v0_is_ivec && (vec0.size() <= vec1.size()))
10384  vds_ = vds_t(vec0_node_ptr_->vds());
10385  else if (v1_is_ivec && (vec1.size() <= vec0.size()))
10386  vds_ = vds_t(vec1_node_ptr_->vds());
10387  else
10388  vds_ = vds_t(std::min(vec0.size(),vec1.size()));
10389 
10390  temp_ = new vector_holder<T>(vds().data(),vds().size());
10392 
10393  initialised_ = true;
10394  }
10395  }
10396 
10398  {
10399  delete temp_;
10400  delete temp_vec_node_;
10401  }
10402 
10403  inline T value() const
10404  {
10405  if (initialised_)
10406  {
10407  binary_node<T>::branch_[0].first->value();
10408  binary_node<T>::branch_[1].first->value();
10409 
10410  T* vec0 = vec0_node_ptr_->vds().data();
10411  T* vec1 = vec1_node_ptr_->vds().data();
10412  T* vec2 = vds().data();
10413 
10414  loop_unroll::details lud(size());
10415  const T* upper_bound = vec2 + lud.upper_bound;
10416 
10417  while (vec2 < upper_bound)
10418  {
10419  #define exprtk_loop(N) \
10420  vec2[N] = Operation::process(vec0[N],vec1[N]); \
10421 
10422  exprtk_loop( 0) exprtk_loop( 1)
10423  exprtk_loop( 2) exprtk_loop( 3)
10424  #ifndef exprtk_disable_superscalar_unroll
10425  exprtk_loop( 4) exprtk_loop( 5)
10426  exprtk_loop( 6) exprtk_loop( 7)
10427  exprtk_loop( 8) exprtk_loop( 9)
10428  exprtk_loop(10) exprtk_loop(11)
10429  exprtk_loop(12) exprtk_loop(13)
10430  exprtk_loop(14) exprtk_loop(15)
10431  #endif
10432 
10433  vec0 += lud.batch_size;
10434  vec1 += lud.batch_size;
10435  vec2 += lud.batch_size;
10436  }
10437 
10438  int i = 0;
10439 
10441  switch (lud.remainder)
10442  {
10443  #define case_stmt(N) \
10444  case N : { vec2[i] = Operation::process(vec0[i],vec1[i]); ++i; } \
10445 
10446  #ifndef exprtk_disable_superscalar_unroll
10447  case_stmt(15) case_stmt(14)
10448  case_stmt(13) case_stmt(12)
10449  case_stmt(11) case_stmt(10)
10450  case_stmt( 9) case_stmt( 8)
10451  case_stmt( 7) case_stmt( 6)
10452  case_stmt( 5) case_stmt( 4)
10453  #endif
10454  case_stmt( 3) case_stmt( 2)
10455  case_stmt( 1)
10456  }
10458 
10459  #undef exprtk_loop
10460  #undef case_stmt
10461 
10462  return (vds().data())[0];
10463  }
10464  else
10465  return std::numeric_limits<T>::quiet_NaN();
10466  }
10467 
10469  {
10470  return temp_vec_node_;
10471  }
10472 
10474  {
10475  return temp_vec_node_;
10476  }
10477 
10478  inline typename expression_node<T>::node_type type() const
10479  {
10481  }
10482 
10483  std::size_t size() const
10484  {
10485  return vds_.size();
10486  }
10487 
10489  {
10490  return vds_;
10491  }
10492 
10493  const vds_t& vds() const
10494  {
10495  return vds_;
10496  }
10497 
10498  private:
10499 
10506  };
10507 
10508  template <typename T, typename Operation>
10510  public vector_interface<T>
10511  {
10512  public:
10513 
10518 
10520  expression_ptr branch0,
10521  expression_ptr branch1)
10522  : binary_node<T>(opr, branch0, branch1),
10523  vec0_node_ptr_(0),
10524  temp_ (0),
10525  temp_vec_node_(0)
10526  {
10527  bool v0_is_ivec = false;
10528 
10530  {
10531  vec0_node_ptr_ = static_cast<vector_node_ptr>(binary_node<T>::branch_[0].first);
10532  }
10533  else if (is_ivector_node(binary_node<T>::branch_[0].first))
10534  {
10535  vector_interface<T>* vi = reinterpret_cast<vector_interface<T>*>(0);
10536 
10537  if (0 != (vi = dynamic_cast<vector_interface<T>*>(binary_node<T>::branch_[0].first)))
10538  {
10539  vec0_node_ptr_ = vi->vec();
10540  v0_is_ivec = true;
10541  }
10542  }
10543 
10544  if (vec0_node_ptr_)
10545  {
10546  if (v0_is_ivec)
10547  vds() = vec0_node_ptr_->vds();
10548  else
10549  vds() = vds_t(vec0_node_ptr_->size());
10550 
10551  temp_ = new vector_holder<T>(vds());
10553  }
10554  }
10555 
10557  {
10558  delete temp_;
10559  delete temp_vec_node_;
10560  }
10561 
10562  inline T value() const
10563  {
10564  if (vec0_node_ptr_)
10565  {
10566  binary_node<T>::branch_[0].first->value();
10567  const T v = binary_node<T>::branch_[1].first->value();
10568 
10569  T* vec0 = vec0_node_ptr_->vds().data();
10570  T* vec1 = vds().data();
10571 
10572  loop_unroll::details lud(size());
10573  const T* upper_bound = vec0 + lud.upper_bound;
10574 
10575  while (vec0 < upper_bound)
10576  {
10577  #define exprtk_loop(N) \
10578  vec1[N] = Operation::process(vec0[N],v); \
10579 
10580  exprtk_loop( 0) exprtk_loop( 1)
10581  exprtk_loop( 2) exprtk_loop( 3)
10582  #ifndef exprtk_disable_superscalar_unroll
10583  exprtk_loop( 4) exprtk_loop( 5)
10584  exprtk_loop( 6) exprtk_loop( 7)
10585  exprtk_loop( 8) exprtk_loop( 9)
10586  exprtk_loop(10) exprtk_loop(11)
10587  exprtk_loop(12) exprtk_loop(13)
10588  exprtk_loop(14) exprtk_loop(15)
10589  #endif
10590 
10591  vec0 += lud.batch_size;
10592  vec1 += lud.batch_size;
10593  }
10594 
10595  int i = 0;
10596 
10598  switch (lud.remainder)
10599  {
10600  #define case_stmt(N) \
10601  case N : { vec1[i] = Operation::process(vec0[i],v); ++i; } \
10602 
10603  #ifndef exprtk_disable_superscalar_unroll
10604  case_stmt(15) case_stmt(14)
10605  case_stmt(13) case_stmt(12)
10606  case_stmt(11) case_stmt(10)
10607  case_stmt( 9) case_stmt( 8)
10608  case_stmt( 7) case_stmt( 6)
10609  case_stmt( 5) case_stmt( 4)
10610  #endif
10611  case_stmt( 3) case_stmt( 2)
10612  case_stmt( 1)
10613  }
10615 
10616  #undef exprtk_loop
10617  #undef case_stmt
10618 
10619  return (vds().data())[0];
10620  }
10621  else
10622  return std::numeric_limits<T>::quiet_NaN();
10623  }
10624 
10626  {
10627  return temp_vec_node_;
10628  }
10629 
10631  {
10632  return temp_vec_node_;
10633  }
10634 
10635  inline typename expression_node<T>::node_type type() const
10636  {
10638  }
10639 
10640  std::size_t size() const
10641  {
10642  return vds().size();
10643  }
10644 
10646  {
10647  return vds_;
10648  }
10649 
10650  const vds_t& vds() const
10651  {
10652  return vds_;
10653  }
10654 
10655  private:
10656 
10661  };
10662 
10663  template <typename T, typename Operation>
10665  public vector_interface<T>
10666  {
10667  public:
10668 
10673 
10675  expression_ptr branch0,
10676  expression_ptr branch1)
10677  : binary_node<T>(opr, branch0, branch1),
10678  vec1_node_ptr_(0),
10679  temp_ (0),
10680  temp_vec_node_(0)
10681  {
10682  bool v1_is_ivec = false;
10683 
10685  {
10686  vec1_node_ptr_ = static_cast<vector_node_ptr>(binary_node<T>::branch_[1].first);
10687  }
10688  else if (is_ivector_node(binary_node<T>::branch_[1].first))
10689  {
10690  vector_interface<T>* vi = reinterpret_cast<vector_interface<T>*>(0);
10691 
10692  if (0 != (vi = dynamic_cast<vector_interface<T>*>(binary_node<T>::branch_[1].first)))
10693  {
10694  vec1_node_ptr_ = vi->vec();
10695  v1_is_ivec = true;
10696  }
10697  }
10698 
10699  if (vec1_node_ptr_)
10700  {
10701  if (v1_is_ivec)
10702  vds() = vec1_node_ptr_->vds();
10703  else
10704  vds() = vds_t(vec1_node_ptr_->size());
10705 
10706  temp_ = new vector_holder<T>(vds());
10708  }
10709  }
10710 
10712  {
10713  delete temp_;
10714  delete temp_vec_node_;
10715  }
10716 
10717  inline T value() const
10718  {
10719  if (vec1_node_ptr_)
10720  {
10721  const T v = binary_node<T>::branch_[0].first->value();
10722  binary_node<T>::branch_[1].first->value();
10723 
10724  T* vec0 = vds().data();
10725  T* vec1 = vec1_node_ptr_->vds().data();
10726 
10727  loop_unroll::details lud(size());
10728  const T* upper_bound = vec0 + lud.upper_bound;
10729 
10730  while (vec0 < upper_bound)
10731  {
10732  #define exprtk_loop(N) \
10733  vec0[N] = Operation::process(v,vec1[N]); \
10734 
10735  exprtk_loop( 0) exprtk_loop( 1)
10736  exprtk_loop( 2) exprtk_loop( 3)
10737  #ifndef exprtk_disable_superscalar_unroll
10738  exprtk_loop( 4) exprtk_loop( 5)
10739  exprtk_loop( 6) exprtk_loop( 7)
10740  exprtk_loop( 8) exprtk_loop( 9)
10741  exprtk_loop(10) exprtk_loop(11)
10742  exprtk_loop(12) exprtk_loop(13)
10743  exprtk_loop(14) exprtk_loop(15)
10744  #endif
10745 
10746  vec0 += lud.batch_size;
10747  vec1 += lud.batch_size;
10748  }
10749 
10750  int i = 0;
10751 
10753  switch (lud.remainder)
10754  {
10755  #define case_stmt(N) \
10756  case N : { vec0[i] = Operation::process(v,vec1[i]); ++i; } \
10757 
10758  #ifndef exprtk_disable_superscalar_unroll
10759  case_stmt(15) case_stmt(14)
10760  case_stmt(13) case_stmt(12)
10761  case_stmt(11) case_stmt(10)
10762  case_stmt( 9) case_stmt( 8)
10763  case_stmt( 7) case_stmt( 6)
10764  case_stmt( 5) case_stmt( 4)
10765  #endif
10766  case_stmt( 3) case_stmt( 2)
10767  case_stmt( 1)
10768  }
10770 
10771  #undef exprtk_loop
10772  #undef case_stmt
10773 
10774  return (vds().data())[0];
10775  }
10776  else
10777  return std::numeric_limits<T>::quiet_NaN();
10778  }
10779 
10781  {
10782  return temp_vec_node_;
10783  }
10784 
10786  {
10787  return temp_vec_node_;
10788  }
10789 
10790  inline typename expression_node<T>::node_type type() const
10791  {
10793  }
10794 
10795  std::size_t size() const
10796  {
10797  return vds().size();
10798  }
10799 
10801  {
10802  return vds_;
10803  }
10804 
10805  const vds_t& vds() const
10806  {
10807  return vds_;
10808  }
10809 
10810  private:
10811 
10816  };
10817 
10818  template <typename T, typename Operation>
10819  class unary_vector_node : public unary_node <T>,
10820  public vector_interface<T>
10821  {
10822  public:
10823 
10828 
10830  : unary_node<T>(opr, branch0),
10831  vec0_node_ptr_(0),
10832  temp_ (0),
10833  temp_vec_node_(0)
10834  {
10835  bool vec0_is_ivec = false;
10836 
10838  {
10840  }
10842  {
10843  vector_interface<T>* vi = reinterpret_cast<vector_interface<T>*>(0);
10844 
10845  if (0 != (vi = dynamic_cast<vector_interface<T>*>(unary_node<T>::branch_)))
10846  {
10847  vec0_node_ptr_ = vi->vec();
10848  vec0_is_ivec = true;
10849  }
10850  }
10851 
10852  if (vec0_node_ptr_)
10853  {
10854  if (vec0_is_ivec)
10855  vds_ = vec0_node_ptr_->vds();
10856  else
10857  vds_ = vds_t(vec0_node_ptr_->size());
10858 
10859  temp_ = new vector_holder<T>(vds());
10861  }
10862  }
10863 
10865  {
10866  delete temp_;
10867  delete temp_vec_node_;
10868  }
10869 
10870  inline T value() const
10871  {
10873 
10874  if (vec0_node_ptr_)
10875  {
10876  T* vec0 = vec0_node_ptr_->vds().data();
10877  T* vec1 = vds().data();
10878 
10879  loop_unroll::details lud(size());
10880  const T* upper_bound = vec0 + lud.upper_bound;
10881 
10882  while (vec0 < upper_bound)
10883  {
10884  #define exprtk_loop(N) \
10885  vec1[N] = Operation::process(vec0[N]); \
10886 
10887  exprtk_loop( 0) exprtk_loop( 1)
10888  exprtk_loop( 2) exprtk_loop( 3)
10889  #ifndef exprtk_disable_superscalar_unroll
10890  exprtk_loop( 4) exprtk_loop( 5)
10891  exprtk_loop( 6) exprtk_loop( 7)
10892  exprtk_loop( 8) exprtk_loop( 9)
10893  exprtk_loop(10) exprtk_loop(11)
10894  exprtk_loop(12) exprtk_loop(13)
10895  exprtk_loop(14) exprtk_loop(15)
10896  #endif
10897 
10898  vec0 += lud.batch_size;
10899  vec1 += lud.batch_size;
10900  }
10901 
10902  int i = 0;
10903 
10905  switch (lud.remainder)
10906  {
10907  #define case_stmt(N) \
10908  case N : { vec1[i] = Operation::process(vec0[i]); ++i; } \
10909 
10910  #ifndef exprtk_disable_superscalar_unroll
10911  case_stmt(15) case_stmt(14)
10912  case_stmt(13) case_stmt(12)
10913  case_stmt(11) case_stmt(10)
10914  case_stmt( 9) case_stmt( 8)
10915  case_stmt( 7) case_stmt( 6)
10916  case_stmt( 5) case_stmt( 4)
10917  #endif
10918  case_stmt( 3) case_stmt( 2)
10919  case_stmt( 1)
10920  }
10922 
10923  #undef exprtk_loop
10924  #undef case_stmt
10925 
10926  return (vds().data())[0];
10927  }
10928  else
10929  return std::numeric_limits<T>::quiet_NaN();
10930  }
10931 
10933  {
10934  return temp_vec_node_;
10935  }
10936 
10938  {
10939  return temp_vec_node_;
10940  }
10941 
10942  inline typename expression_node<T>::node_type type() const
10943  {
10945  }
10946 
10947  std::size_t size() const
10948  {
10949  return vds().size();
10950  }
10951 
10953  {
10954  return vds_;
10955  }
10956 
10957  const vds_t& vds() const
10958  {
10959  return vds_;
10960  }
10961 
10962  private:
10963 
10968  };
10969 
10970  template <typename T>
10971  class scand_node : public binary_node<T>
10972  {
10973  public:
10974 
10976 
10978  expression_ptr branch0,
10979  expression_ptr branch1)
10980  : binary_node<T>(opr, branch0, branch1)
10981  {}
10982 
10983  inline T value() const
10984  {
10985  return (
10986  std::not_equal_to<T>()
10987  (T(0),binary_node<T>::branch_[0].first->value()) &&
10988  std::not_equal_to<T>()
10989  (T(0),binary_node<T>::branch_[1].first->value())
10990  ) ? T(1) : T(0);
10991  }
10992  };
10993 
10994  template <typename T>
10995  class scor_node : public binary_node<T>
10996  {
10997  public:
10998 
11000 
11002  expression_ptr branch0,
11003  expression_ptr branch1)
11004  : binary_node<T>(opr, branch0, branch1)
11005  {}
11006 
11007  inline T value() const
11008  {
11009  return (
11010  std::not_equal_to<T>()
11011  (T(0),binary_node<T>::branch_[0].first->value()) ||
11012  std::not_equal_to<T>()
11013  (T(0),binary_node<T>::branch_[1].first->value())
11014  ) ? T(1) : T(0);
11015  }
11016  };
11017 
11018  template <typename T, typename IFunction, std::size_t N>
11020  {
11021  public:
11022 
11023  // Function of N paramters.
11025  typedef std::pair<expression_ptr,bool> branch_t;
11026  typedef IFunction ifunction;
11027 
11029  : function_((N == func->param_count) ? func : reinterpret_cast<ifunction*>(0)),
11030  parameter_count_(func->param_count)
11031  {}
11032 
11034  {
11035  cleanup_branches::execute<T,N>(branch_);
11036  }
11037 
11038  template <std::size_t NumBranches>
11039  bool init_branches(expression_ptr (&b)[NumBranches])
11040  {
11041  // Needed for incompetent and broken msvc compiler versions
11042  #ifdef _MSC_VER
11043  #pragma warning(push)
11044  #pragma warning(disable: 4127)
11045  #endif
11046  if (N != NumBranches)
11047  return false;
11048  else
11049  {
11050  for (std::size_t i = 0; i < NumBranches; ++i)
11051  {
11052  if (b[i])
11053  branch_[i] = std::make_pair(b[i],branch_deletable(b[i]));
11054  else
11055  return false;
11056  }
11057  return true;
11058  }
11059  #ifdef _MSC_VER
11060  #pragma warning(pop)
11061  #endif
11062  }
11063 
11064  inline bool operator <(const function_N_node<T,IFunction,N>& fn) const
11065  {
11066  return this < (&fn);
11067  }
11068 
11069  inline T value() const
11070  {
11071  // Needed for incompetent and broken msvc compiler versions
11072  #ifdef _MSC_VER
11073  #pragma warning(push)
11074  #pragma warning(disable: 4127)
11075  #endif
11076  if ((0 == function_) || (0 == N))
11077  return std::numeric_limits<T>::quiet_NaN();
11078  else
11079  {
11080  T v[N];
11082  return invoke<T,N>::execute(*function_,v);
11083  }
11084  #ifdef _MSC_VER
11085  #pragma warning(pop)
11086  #endif
11087  }
11088 
11089  template <typename T_, std::size_t BranchCount>
11091  {
11092  static inline void execute(T_ (&v)[BranchCount], const branch_t (&b)[BranchCount])
11093  {
11094  for (std::size_t i = 0; i < BranchCount; ++i)
11095  {
11096  v[i] = b[i].first->value();
11097  }
11098  }
11099  };
11100 
11101  template <typename T_>
11102  struct evaluate_branches <T_,5>
11103  {
11104  static inline void execute(T_ (&v)[5], const branch_t (&b)[5])
11105  {
11106  v[0] = b[0].first->value();
11107  v[1] = b[1].first->value();
11108  v[2] = b[2].first->value();
11109  v[3] = b[3].first->value();
11110  v[4] = b[4].first->value();
11111  }
11112  };
11113 
11114  template <typename T_>
11115  struct evaluate_branches <T_,4>
11116  {
11117  static inline void execute(T_ (&v)[4], const branch_t (&b)[4])
11118  {
11119  v[0] = b[0].first->value();
11120  v[1] = b[1].first->value();
11121  v[2] = b[2].first->value();
11122  v[3] = b[3].first->value();
11123  }
11124  };
11125 
11126  template <typename T_>
11127  struct evaluate_branches <T_,3>
11128  {
11129  static inline void execute(T_ (&v)[3], const branch_t (&b)[3])
11130  {
11131  v[0] = b[0].first->value();
11132  v[1] = b[1].first->value();
11133  v[2] = b[2].first->value();
11134  }
11135  };
11136 
11137  template <typename T_>
11138  struct evaluate_branches <T_,2>
11139  {
11140  static inline void execute(T_ (&v)[2], const branch_t (&b)[2])
11141  {
11142  v[0] = b[0].first->value();
11143  v[1] = b[1].first->value();
11144  }
11145  };
11146 
11147  template <typename T_>
11148  struct evaluate_branches <T_,1>
11149  {
11150  static inline void execute(T_ (&v)[1], const branch_t (&b)[1])
11151  {
11152  v[0] = b[0].first->value();
11153  }
11154  };
11155 
11156  template <typename T_, std::size_t ParamCount>
11157  struct invoke { static inline T execute(ifunction&, branch_t (&)[ParamCount]) { return std::numeric_limits<T_>::quiet_NaN(); } };
11158 
11159  template <typename T_>
11160  struct invoke<T_,20>
11161  {
11162  static inline T_ execute(ifunction& f, T_ (&v)[20])
11163  { return f(v[0],v[1],v[2],v[3],v[4],v[5],v[6],v[7],v[8],v[9],v[10],v[11],v[12],v[13],v[14],v[15],v[16],v[17],v[18],v[19]); }
11164  };
11165 
11166  template <typename T_>
11167  struct invoke<T_,19>
11168  {
11169  static inline T_ execute(ifunction& f, T_ (&v)[19])
11170  { return f(v[0],v[1],v[2],v[3],v[4],v[5],v[6],v[7],v[8],v[9],v[10],v[11],v[12],v[13],v[14],v[15],v[16],v[17],v[18]); }
11171  };
11172 
11173  template <typename T_>
11174  struct invoke<T_,18>
11175  {
11176  static inline T_ execute(ifunction& f, T_ (&v)[18])
11177  { return f(v[0],v[1],v[2],v[3],v[4],v[5],v[6],v[7],v[8],v[9],v[10],v[11],v[12],v[13],v[14],v[15],v[16],v[17]); }
11178  };
11179 
11180  template <typename T_>
11181  struct invoke<T_,17>
11182  {
11183  static inline T_ execute(ifunction& f, T_ (&v)[17])
11184  { return f(v[0],v[1],v[2],v[3],v[4],v[5],v[6],v[7],v[8],v[9],v[10],v[11],v[12],v[13],v[14],v[15],v[16]); }
11185  };
11186 
11187  template <typename T_>
11188  struct invoke<T_,16>
11189  {
11190  static inline T_ execute(ifunction& f, T_ (&v)[16])
11191  { return f(v[0],v[1],v[2],v[3],v[4],v[5],v[6],v[7],v[8],v[9],v[10],v[11],v[12],v[13],v[14],v[15]); }
11192  };
11193 
11194  template <typename T_>
11195  struct invoke<T_,15>
11196  {
11197  static inline T_ execute(ifunction& f, T_ (&v)[15])
11198  { return f(v[0],v[1],v[2],v[3],v[4],v[5],v[6],v[7],v[8],v[9],v[10],v[11],v[12],v[13],v[14]); }
11199  };
11200 
11201  template <typename T_>
11202  struct invoke<T_,14>
11203  {
11204  static inline T_ execute(ifunction& f, T_ (&v)[14])
11205  { return f(v[0],v[1],v[2],v[3],v[4],v[5],v[6],v[7],v[8],v[9],v[10],v[11],v[12],v[13]); }
11206  };
11207 
11208  template <typename T_>
11209  struct invoke<T_,13>
11210  {
11211  static inline T_ execute(ifunction& f, T_ (&v)[13])
11212  { return f(v[0],v[1],v[2],v[3],v[4],v[5],v[6],v[7],v[8],v[9],v[10],v[11],v[12]); }
11213  };
11214 
11215  template <typename T_>
11216  struct invoke<T_,12>
11217  {
11218  static inline T_ execute(ifunction& f, T_ (&v)[12])
11219  { return f(v[0],v[1],v[2],v[3],v[4],v[5],v[6],v[7],v[8],v[9],v[10],v[11]); }
11220  };
11221 
11222  template <typename T_>
11223  struct invoke<T_,11>
11224  {
11225  static inline T_ execute(ifunction& f, T_ (&v)[11])
11226  { return f(v[0],v[1],v[2],v[3],v[4],v[5],v[6],v[7],v[8],v[9],v[10]); }
11227  };
11228 
11229  template <typename T_>
11230  struct invoke<T_,10>
11231  {
11232  static inline T_ execute(ifunction& f, T_ (&v)[10])
11233  { return f(v[0],v[1],v[2],v[3],v[4],v[5],v[6],v[7],v[8],v[9]); }
11234  };
11235 
11236  template <typename T_>
11237  struct invoke<T_,9>
11238  {
11239  static inline T_ execute(ifunction& f, T_ (&v)[9])
11240  { return f(v[0],v[1],v[2],v[3],v[4],v[5],v[6],v[7],v[8]); }
11241  };
11242 
11243  template <typename T_>
11244  struct invoke<T_,8>
11245  {
11246  static inline T_ execute(ifunction& f, T_ (&v)[8])
11247  { return f(v[0],v[1],v[2],v[3],v[4],v[5],v[6],v[7]); }
11248  };
11249 
11250  template <typename T_>
11251  struct invoke<T_,7>
11252  {
11253  static inline T_ execute(ifunction& f, T_ (&v)[7])
11254  { return f(v[0],v[1],v[2],v[3],v[4],v[5],v[6]); }
11255  };
11256 
11257  template <typename T_>
11258  struct invoke<T_,6>
11259  {
11260  static inline T_ execute(ifunction& f, T_ (&v)[6])
11261  { return f(v[0],v[1],v[2],v[3],v[4],v[5]); }
11262  };
11263 
11264  template <typename T_>
11265  struct invoke<T_,5>
11266  {
11267  static inline T_ execute(ifunction& f, T_ (&v)[5])
11268  { return f(v[0],v[1],v[2],v[3],v[4]); }
11269  };
11270 
11271  template <typename T_>
11272  struct invoke<T_,4>
11273  {
11274  static inline T_ execute(ifunction& f, T_ (&v)[4])
11275  { return f(v[0],v[1],v[2],v[3]); }
11276  };
11277 
11278  template <typename T_>
11279  struct invoke<T_,3>
11280  {
11281  static inline T_ execute(ifunction& f, T_ (&v)[3])
11282  { return f(v[0],v[1],v[2]); }
11283  };
11284 
11285  template <typename T_>
11286  struct invoke<T_,2>
11287  {
11288  static inline T_ execute(ifunction& f, T_ (&v)[2])
11289  { return f(v[0],v[1]); }
11290  };
11291 
11292  template <typename T_>
11293  struct invoke<T_,1>
11294  {
11295  static inline T_ execute(ifunction& f, T_ (&v)[1])
11296  { return f(v[0]); }
11297  };
11298 
11299  inline typename expression_node<T>::node_type type() const
11300  {
11302  }
11303 
11304  private:
11305 
11307  std::size_t parameter_count_;
11309  };
11310 
11311  template <typename T, typename IFunction>
11312  class function_N_node<T,IFunction,0> : public expression_node<T>
11313  {
11314  public:
11315 
11317  typedef IFunction ifunction;
11318 
11320  : function_((0 == func->param_count) ? func : reinterpret_cast<ifunction*>(0))
11321  {}
11322 
11323  inline bool operator <(const function_N_node<T,IFunction,0>& fn) const
11324  {
11325  return this < (&fn);
11326  }
11327 
11328  inline T value() const
11329  {
11330  if (function_)
11331  return (*function_)();
11332  else
11333  return std::numeric_limits<T>::quiet_NaN();
11334  }
11335 
11336  inline typename expression_node<T>::node_type type() const
11337  {
11339  }
11340 
11341  private:
11342 
11344  };
11345 
11346  template <typename T, typename VarArgFunction>
11348  {
11349  public:
11350 
11352 
11353  vararg_function_node(VarArgFunction* func,
11354  const std::vector<expression_ptr>& arg_list)
11355  : function_(func),
11356  arg_list_(arg_list)
11357  {
11358  value_list_.resize(arg_list.size(),std::numeric_limits<T>::quiet_NaN());
11359  }
11360 
11362  {
11363  for (std::size_t i = 0; i < arg_list_.size(); ++i)
11364  {
11366  {
11367  destroy_node(arg_list_[i]);
11368  }
11369  }
11370  }
11371 
11372  inline bool operator <(const vararg_function_node<T,VarArgFunction>& fn) const
11373  {
11374  return this < (&fn);
11375  }
11376 
11377  inline T value() const
11378  {
11379  if (function_)
11380  {
11382  return (*function_)(value_list_);
11383  }
11384  else
11385  return std::numeric_limits<T>::quiet_NaN();
11386  }
11387 
11388  inline typename expression_node<T>::node_type type() const
11389  {
11391  }
11392 
11393  private:
11394 
11395  inline void populate_value_list() const
11396  {
11397  for (std::size_t i = 0; i < arg_list_.size(); ++i)
11398  {
11399  value_list_[i] = arg_list_[i]->value();
11400  }
11401  }
11402 
11403  VarArgFunction* function_;
11404  std::vector<expression_ptr> arg_list_;
11405  mutable std::vector<T> value_list_;
11406  };
11407 
11408  template <typename T, typename GenericFunction>
11410  {
11411  public:
11412 
11422  typedef std::pair<expression_ptr,bool> branch_t;
11423  typedef std::pair<void*,std::size_t> void_t;
11424  typedef std::vector<T> tmp_vs_t;
11425  typedef std::vector<type_store_t> typestore_list_t;
11426  typedef std::vector<range_data_type_t> range_list_t;
11427 
11428  generic_function_node(const std::vector<expression_ptr>& arg_list,
11429  GenericFunction* func = (GenericFunction*)(0))
11430  : function_(func),
11431  arg_list_(arg_list)
11432  {}
11433 
11435  {
11437  }
11438 
11439  virtual bool init_branches()
11440  {
11441  expr_as_vec1_store_.resize(arg_list_.size(),T(0) );
11442  typestore_list_ .resize(arg_list_.size(),type_store_t() );
11443  range_list_ .resize(arg_list_.size(),range_data_type_t());
11444  branch_ .resize(arg_list_.size(),branch_t((expression_ptr)0,false));
11445 
11446  for (std::size_t i = 0; i < arg_list_.size(); ++i)
11447  {
11448  type_store_t& ts = typestore_list_[i];
11449 
11450  if (0 == arg_list_[i])
11451  return false;
11452  else if (is_ivector_node(arg_list_[i]))
11453  {
11454  vector_interface<T>* vi = reinterpret_cast<vector_interface<T>*>(0);
11455 
11456  if (0 == (vi = dynamic_cast<vector_interface<T>*>(arg_list_[i])))
11457  return false;
11458 
11459  ts.size = vi->size();
11460  ts.data = vi->vds().data();
11462  }
11463  #ifndef exprtk_disable_string_capabilities
11464  else if (is_generally_string_node(arg_list_[i]))
11465  {
11466  string_base_node<T>* sbn = reinterpret_cast<string_base_node<T>*>(0);
11467 
11468  if (0 == (sbn = dynamic_cast<string_base_node<T>*>(arg_list_[i])))
11469  return false;
11470 
11471  ts.size = sbn->size();
11472  ts.data = reinterpret_cast<void*>(const_cast<char_ptr>(sbn->base()));
11474 
11475  range_list_[i].data = ts.data;
11476  range_list_[i].size = ts.size;
11477  range_list_[i].type_size = sizeof(char);
11478  range_list_[i].str_node = sbn;
11479 
11480  range_interface_t* ri = reinterpret_cast<range_interface_t*>(0);
11481 
11482  if (0 == (ri = dynamic_cast<range_interface_t*>(arg_list_[i])))
11483  return false;
11484 
11485  range_t& rp = ri->range_ref();
11486 
11487  if (
11488  rp.const_range() &&
11490  )
11491  {
11492  ts.size = rp.const_size();
11493  ts.data = static_cast<char_ptr>(ts.data) + rp.n0_c.second;
11494  range_list_[i].range = reinterpret_cast<range_t*>(0);
11495  }
11496  else
11497  range_list_[i].range = &(ri->range_ref());
11498  }
11499  #endif
11500  else if (is_variable_node(arg_list_[i]))
11501  {
11503 
11504  if (0 == (var = dynamic_cast<variable_node_ptr_t>(arg_list_[i])))
11505  return false;
11506 
11507  ts.size = 1;
11508  ts.data = &var->ref();
11510  }
11511  else
11512  {
11513  ts.size = 1;
11514  ts.data = reinterpret_cast<void*>(&expr_as_vec1_store_[i]);
11516  }
11517 
11518  branch_[i] = std::make_pair(arg_list_[i],branch_deletable(arg_list_[i]));
11519  }
11520 
11521  return true;
11522  }
11523 
11524  inline bool operator <(const generic_function_node<T,GenericFunction>& fn) const
11525  {
11526  return this < (&fn);
11527  }
11528 
11529  inline T value() const
11530  {
11531  if (function_)
11532  {
11533  if (populate_value_list())
11534  {
11535  typedef typename GenericFunction::parameter_list_t parameter_list_t;
11536 
11537  return (*function_)(parameter_list_t(typestore_list_));
11538  }
11539  }
11540 
11541  return std::numeric_limits<T>::quiet_NaN();
11542  }
11543 
11544  inline typename expression_node<T>::node_type type() const
11545  {
11547  }
11548 
11549  protected:
11550 
11551  inline virtual bool populate_value_list() const
11552  {
11553  for (std::size_t i = 0; i < branch_.size(); ++i)
11554  {
11555  expr_as_vec1_store_[i] = branch_[i].first->value();
11556  }
11557 
11558  for (std::size_t i = 0; i < branch_.size(); ++i)
11559  {
11560  range_data_type_t& rdt = range_list_[i];
11561 
11562  if (rdt.range)
11563  {
11564  range_t& rp = (*rdt.range);
11565  std::size_t r0 = 0;
11566  std::size_t r1 = 0;
11567 
11568  if (rp(r0,r1,rdt.size))
11569  {
11570  type_store_t& ts = typestore_list_[i];
11571 
11572  ts.size = rp.cache_size();
11573  #ifndef exprtk_disable_string_capabilities
11574  if (ts.type == type_store_t::e_string)
11575  ts.data = const_cast<char_ptr>(rdt.str_node->base()) + rp.cache.first;
11576  else
11577  #endif
11578  ts.data = static_cast<char_ptr>(rdt.data) + (rp.cache.first * rdt.type_size);
11579  }
11580  else
11581  return false;
11582  }
11583  }
11584 
11585  return true;
11586  }
11587 
11588  GenericFunction* function_;
11590 
11591  private:
11592 
11593  std::vector<expression_ptr> arg_list_;
11594  std::vector<branch_t> branch_;
11597  };
11598 
11599  #ifndef exprtk_disable_string_capabilities
11600  template <typename T, typename StringFunction>
11601  class string_function_node : public generic_function_node<T,StringFunction>,
11602  public string_base_node<T>,
11603  public range_interface <T>
11604  {
11605  public:
11606 
11609 
11610  string_function_node(StringFunction* func,
11611  const std::vector<typename gen_function_t::expression_ptr>& arg_list)
11612  : gen_function_t(arg_list,func)
11613  {
11614  range_.n0_c = std::make_pair<bool,std::size_t>(true,0);
11615  range_.n1_c = std::make_pair<bool,std::size_t>(true,0);
11616  range_.cache.first = range_.n0_c.second;
11617  range_.cache.second = range_.n1_c.second;
11618  }
11619 
11620  inline bool operator <(const string_function_node<T,StringFunction>& fn) const
11621  {
11622  return this < (&fn);
11623  }
11624 
11625  inline T value() const
11626  {
11627  T result = std::numeric_limits<T>::quiet_NaN();
11628 
11630  {
11632  {
11633  typedef typename StringFunction::parameter_list_t parameter_list_t;
11634 
11635  result = (*gen_function_t::function_)(ret_string_,
11636  parameter_list_t(gen_function_t::typestore_list_));
11637 
11638  range_.n1_c.second = ret_string_.size() - 1;
11639  range_.cache.second = range_.n1_c.second;
11640 
11641  return result;
11642  }
11643  }
11644 
11645  return result;
11646  }
11647 
11648  inline typename expression_node<T>::node_type type() const
11649  {
11651  }
11652 
11653  std::string str() const
11654  {
11655  return ret_string_;
11656  }
11657 
11658  char_cptr base() const
11659  {
11660  return &ret_string_[0];
11661  }
11662 
11663  std::size_t size() const
11664  {
11665  return ret_string_.size();
11666  }
11667 
11669  {
11670  return range_;
11671  }
11672 
11673  const range_t& range_ref() const
11674  {
11675  return range_;
11676  }
11677 
11678  protected:
11679 
11680  mutable range_t range_;
11681  mutable std::string ret_string_;
11682  };
11683  #endif
11684 
11685  template <typename T, typename GenericFunction>
11686  class multimode_genfunction_node : public generic_function_node<T,GenericFunction>
11687  {
11688  public:
11689 
11692 
11693  multimode_genfunction_node(GenericFunction* func,
11694  const std::size_t& param_seq_index,
11695  const std::vector<typename gen_function_t::expression_ptr>& arg_list)
11696  : gen_function_t(arg_list,func),
11697  param_seq_index_(param_seq_index)
11698  {}
11699 
11700  inline T value() const
11701  {
11702  T result = std::numeric_limits<T>::quiet_NaN();
11703 
11705  {
11707  {
11708  typedef typename GenericFunction::parameter_list_t parameter_list_t;
11709 
11711  parameter_list_t(gen_function_t::typestore_list_));
11712  }
11713  }
11714 
11715  return result;
11716  }
11717 
11718  inline typename expression_node<T>::node_type type() const
11719  {
11721  }
11722 
11723  private:
11724 
11725  std::size_t param_seq_index_;
11726  };
11727 
11728  #ifndef exprtk_disable_string_capabilities
11729  template <typename T, typename StringFunction>
11730  class multimode_strfunction_node : public string_function_node<T,StringFunction>
11731  {
11732  public:
11733 
11736 
11737  multimode_strfunction_node(StringFunction* func,
11738  const std::size_t& param_seq_index,
11739  const std::vector<typename str_function_t::expression_ptr>& arg_list)
11740  : str_function_t(func,arg_list),
11741  param_seq_index_(param_seq_index)
11742  {}
11743 
11744  inline T value() const
11745  {
11746  T result = std::numeric_limits<T>::quiet_NaN();
11747 
11749  {
11751  {
11752  typedef typename StringFunction::parameter_list_t parameter_list_t;
11753 
11754  result = (*str_function_t::function_)(param_seq_index_,
11756  parameter_list_t(str_function_t::typestore_list_));
11757 
11758  str_function_t::range_.n1_c.second = str_function_t::ret_string_.size() - 1;
11760 
11761  return result;
11762  }
11763  }
11764 
11765  return result;
11766  }
11767 
11768  inline typename expression_node<T>::node_type type() const
11769  {
11771  }
11772 
11773  private:
11774 
11775  const std::size_t param_seq_index_;
11776  };
11777  #endif
11778 
11780  {};
11781 
11782  template <typename T>
11784  {
11785  public:
11786 
11787  virtual ~null_igenfunc()
11788  {}
11789 
11792 
11793  inline virtual T operator() (parameter_list_t)
11794  {
11795  return std::numeric_limits<T>::quiet_NaN();
11796  }
11797  };
11798 
11799  #ifndef exprtk_disable_return_statement
11800  template <typename T>
11801  class return_node : public generic_function_node<T,null_igenfunc<T> >
11802  {
11803  public:
11804 
11809 
11810  return_node(const std::vector<typename gen_function_t::expression_ptr>& arg_list,
11811  results_context_t& rc)
11812  : gen_function_t (arg_list),
11813  results_context_(&rc)
11814  {}
11815 
11816  inline T value() const
11817  {
11818  if (
11819  (0 != results_context_) &&
11821  )
11822  {
11823  typedef typename type_store<T>::parameter_list parameter_list_t;
11824 
11826  assign(parameter_list_t(gen_function_t::typestore_list_));
11827 
11828  throw return_exception();
11829  }
11830 
11831  return std::numeric_limits<T>::quiet_NaN();
11832  }
11833 
11834  inline typename expression_node<T>::node_type type() const
11835  {
11837  }
11838 
11839  private:
11840 
11842  };
11843 
11844  template <typename T>
11845  class return_envelope_node : public expression_node<T>
11846  {
11847  public:
11848 
11851 
11853  : results_context_(&rc ),
11854  return_invoked_ (false),
11855  body_ (body ),
11857  {}
11858 
11860  {
11861  if (body_ && body_deletable_)
11862  {
11864  }
11865  }
11866 
11867  inline T value() const
11868  {
11869  try
11870  {
11871  return_invoked_ = false;
11873 
11874  return body_->value();
11875  }
11876  catch(const return_exception&)
11877  {
11878  return_invoked_ = true;
11879  return std::numeric_limits<T>::quiet_NaN();
11880  }
11881  }
11882 
11883  inline typename expression_node<T>::node_type type() const
11884  {
11886  }
11887 
11888  inline bool* retinvk_ptr()
11889  {
11890  return &return_invoked_;
11891  }
11892 
11893  private:
11894 
11896  mutable bool return_invoked_;
11898  const bool body_deletable_;
11899  };
11900  #endif
11901 
11902  #define exprtk_define_unary_op(OpName) \
11903  template <typename T> \
11904  struct OpName##_op \
11905  { \
11906  typedef typename functor_t<T>::Type Type; \
11907  typedef typename expression_node<T>::node_type node_t; \
11908  \
11909  static inline T process(Type v) \
11910  { \
11911  return numeric:: OpName (v); \
11912  } \
11913  \
11914  static inline node_t type() \
11915  { \
11916  return expression_node<T>::e_##OpName; \
11917  } \
11918  \
11919  static inline details::operator_type operation() \
11920  { \
11921  return details::e_##OpName; \
11922  } \
11923  }; \
11924 
11926  exprtk_define_unary_op(acos )
11927  exprtk_define_unary_op(acosh)
11928  exprtk_define_unary_op(asin )
11929  exprtk_define_unary_op(asinh)
11930  exprtk_define_unary_op(atan )
11931  exprtk_define_unary_op(atanh)
11932  exprtk_define_unary_op(ceil )
11934  exprtk_define_unary_op(cosh )
11940  exprtk_define_unary_op(erfc )
11942  exprtk_define_unary_op(expm1)
11943  exprtk_define_unary_op(floor)
11944  exprtk_define_unary_op(frac )
11947  exprtk_define_unary_op(log10)
11949  exprtk_define_unary_op(log1p)
11950  exprtk_define_unary_op(ncdf )
11952  exprtk_define_unary_op(notl )
11955  exprtk_define_unary_op(round)
11959  exprtk_define_unary_op(sinc )
11960  exprtk_define_unary_op(sinh )
11961  exprtk_define_unary_op(sqrt )
11963  exprtk_define_unary_op(tanh )
11964  exprtk_define_unary_op(trunc)
11965  #undef exprtk_define_unary_op
11966 
11967  template <typename T>
11968  struct opr_base
11969  {
11970  typedef typename details::functor_t<T>::Type Type;
11971  typedef typename details::functor_t<T>::RefType RefType;
11972  typedef typename details::functor_t<T> functor_t;
11973  typedef typename functor_t::qfunc_t quaternary_functor_t;
11974  typedef typename functor_t::tfunc_t trinary_functor_t;
11975  typedef typename functor_t::bfunc_t binary_functor_t;
11976  typedef typename functor_t::ufunc_t unary_functor_t;
11977  };
11978 
11979  template <typename T>
11980  struct add_op : public opr_base<T>
11981  {
11982  typedef typename opr_base<T>::Type Type;
11983  typedef typename opr_base<T>::RefType RefType;
11984  static inline T process(Type t1, Type t2) { return t1 + t2; }
11985  static inline T process(Type t1, Type t2, Type t3) { return t1 + t2 + t3; }
11986  static inline void assign(RefType t1, Type t2) { t1 += t2; }
11987  static inline typename expression_node<T>::node_type type() { return expression_node<T>::e_add; }
11989  };
11990 
11991  template <typename T>
11992  struct mul_op : public opr_base<T>
11993  {
11994  typedef typename opr_base<T>::Type Type;
11995  typedef typename opr_base<T>::RefType RefType;
11996  static inline T process(Type t1, Type t2) { return t1 * t2; }
11997  static inline T process(Type t1, Type t2, Type t3) { return t1 * t2 * t3; }
11998  static inline void assign(RefType t1, Type t2) { t1 *= t2; }
11999  static inline typename expression_node<T>::node_type type() { return expression_node<T>::e_mul; }
12001  };
12002 
12003  template <typename T>
12004  struct sub_op : public opr_base<T>
12005  {
12006  typedef typename opr_base<T>::Type Type;
12007  typedef typename opr_base<T>::RefType RefType;
12008  static inline T process(Type t1, Type t2) { return t1 - t2; }
12009  static inline T process(Type t1, Type t2, Type t3) { return t1 - t2 - t3; }
12010  static inline void assign(RefType t1, Type t2) { t1 -= t2; }
12011  static inline typename expression_node<T>::node_type type() { return expression_node<T>::e_sub; }
12013  };
12014 
12015  template <typename T>
12016  struct div_op : public opr_base<T>
12017  {
12018  typedef typename opr_base<T>::Type Type;
12019  typedef typename opr_base<T>::RefType RefType;
12020  static inline T process(Type t1, Type t2) { return t1 / t2; }
12021  static inline T process(Type t1, Type t2, Type t3) { return t1 / t2 / t3; }
12022  static inline void assign(RefType t1, Type t2) { t1 /= t2; }
12023  static inline typename expression_node<T>::node_type type() { return expression_node<T>::e_div; }
12025  };
12026 
12027  template <typename T>
12028  struct mod_op : public opr_base<T>
12029  {
12030  typedef typename opr_base<T>::Type Type;
12031  typedef typename opr_base<T>::RefType RefType;
12032  static inline T process(Type t1, Type t2) { return numeric::modulus<T>(t1,t2); }
12033  static inline void assign(RefType t1, Type t2) { t1 = numeric::modulus<T>(t1,t2); }
12034  static inline typename expression_node<T>::node_type type() { return expression_node<T>::e_mod; }
12036  };
12037 
12038  template <typename T>
12039  struct pow_op : public opr_base<T>
12040  {
12041  typedef typename opr_base<T>::Type Type;
12042  typedef typename opr_base<T>::RefType RefType;
12043  static inline T process(Type t1, Type t2) { return numeric::pow<T>(t1,t2); }
12044  static inline void assign(RefType t1, Type t2) { t1 = numeric::pow<T>(t1,t2); }
12045  static inline typename expression_node<T>::node_type type() { return expression_node<T>::e_pow; }
12047  };
12048 
12049  template <typename T>
12050  struct lt_op : public opr_base<T>
12051  {
12052  typedef typename opr_base<T>::Type Type;
12053  static inline T process(Type t1, Type t2) { return ((t1 < t2) ? T(1) : T(0)); }
12054  static inline T process(const std::string& t1, const std::string& t2) { return ((t1 < t2) ? T(1) : T(0)); }
12055  static inline typename expression_node<T>::node_type type() { return expression_node<T>::e_lt; }
12056  static inline details::operator_type operation() { return details::e_lt; }
12057  };
12058 
12059  template <typename T>
12060  struct lte_op : public opr_base<T>
12061  {
12062  typedef typename opr_base<T>::Type Type;
12063  static inline T process(Type t1, Type t2) { return ((t1 <= t2) ? T(1) : T(0)); }
12064  static inline T process(const std::string& t1, const std::string& t2) { return ((t1 <= t2) ? T(1) : T(0)); }
12065  static inline typename expression_node<T>::node_type type() { return expression_node<T>::e_lte; }
12067  };
12068 
12069  template <typename T>
12070  struct gt_op : public opr_base<T>
12071  {
12072  typedef typename opr_base<T>::Type Type;
12073  static inline T process(Type t1, Type t2) { return ((t1 > t2) ? T(1) : T(0)); }
12074  static inline T process(const std::string& t1, const std::string& t2) { return ((t1 > t2) ? T(1) : T(0)); }
12075  static inline typename expression_node<T>::node_type type() { return expression_node<T>::e_gt; }
12076  static inline details::operator_type operation() { return details::e_gt; }
12077  };
12078 
12079  template <typename T>
12080  struct gte_op : public opr_base<T>
12081  {
12082  typedef typename opr_base<T>::Type Type;
12083  static inline T process(Type t1, Type t2) { return ((t1 >= t2) ? T(1) : T(0)); }
12084  static inline T process(const std::string& t1, const std::string& t2) { return ((t1 >= t2) ? T(1) : T(0)); }
12085  static inline typename expression_node<T>::node_type type() { return expression_node<T>::e_gte; }
12087  };
12088 
12089  template <typename T>
12090  struct eq_op : public opr_base<T>
12091  {
12092  typedef typename opr_base<T>::Type Type;
12093  static inline T process(Type t1, Type t2) { return (std::equal_to<T>()(t1,t2) ? T(1) : T(0)); }
12094  static inline T process(const std::string& t1, const std::string& t2) { return ((t1 == t2) ? T(1) : T(0)); }
12095  static inline typename expression_node<T>::node_type type() { return expression_node<T>::e_eq; }
12096  static inline details::operator_type operation() { return details::e_eq; }
12097  };
12098 
12099  template <typename T>
12100  struct equal_op : public opr_base<T>
12101  {
12102  typedef typename opr_base<T>::Type Type;
12103  static inline T process(Type t1, Type t2) { return numeric::equal(t1,t2); }
12104  static inline T process(const std::string& t1, const std::string& t2) { return ((t1 == t2) ? T(1) : T(0)); }
12105  static inline typename expression_node<T>::node_type type() { return expression_node<T>::e_eq; }
12107  };
12108 
12109  template <typename T>
12110  struct ne_op : public opr_base<T>
12111  {
12112  typedef typename opr_base<T>::Type Type;
12113  static inline T process(Type t1, Type t2) { return (std::not_equal_to<T>()(t1,t2) ? T(1) : T(0)); }
12114  static inline T process(const std::string& t1, const std::string& t2) { return ((t1 != t2) ? T(1) : T(0)); }
12115  static inline typename expression_node<T>::node_type type() { return expression_node<T>::e_ne; }
12116  static inline details::operator_type operation() { return details::e_ne; }
12117  };
12118 
12119  template <typename T>
12120  struct and_op : public opr_base<T>
12121  {
12122  typedef typename opr_base<T>::Type Type;
12123  static inline T process(Type t1, Type t2) { return (details::is_true(t1) && details::is_true(t2)) ? T(1) : T(0); }
12124  static inline typename expression_node<T>::node_type type() { return expression_node<T>::e_and; }
12126  };
12127 
12128  template <typename T>
12129  struct nand_op : public opr_base<T>
12130  {
12131  typedef typename opr_base<T>::Type Type;
12132  static inline T process(Type t1, Type t2) { return (details::is_true(t1) && details::is_true(t2)) ? T(0) : T(1); }
12135  };
12136 
12137  template <typename T>
12138  struct or_op : public opr_base<T>
12139  {
12140  typedef typename opr_base<T>::Type Type;
12141  static inline T process(Type t1, Type t2) { return (details::is_true(t1) || details::is_true(t2)) ? T(1) : T(0); }
12142  static inline typename expression_node<T>::node_type type() { return expression_node<T>::e_or; }
12143  static inline details::operator_type operation() { return details::e_or; }
12144  };
12145 
12146  template <typename T>
12147  struct nor_op : public opr_base<T>
12148  {
12149  typedef typename opr_base<T>::Type Type;
12150  static inline T process(Type t1, Type t2) { return (details::is_true(t1) || details::is_true(t2)) ? T(0) : T(1); }
12151  static inline typename expression_node<T>::node_type type() { return expression_node<T>::e_nor; }
12153  };
12154 
12155  template <typename T>
12156  struct xor_op : public opr_base<T>
12157  {
12158  typedef typename opr_base<T>::Type Type;
12159  static inline T process(Type t1, Type t2) { return numeric::xor_opr<T>(t1,t2); }
12160  static inline typename expression_node<T>::node_type type() { return expression_node<T>::e_nor; }
12162  };
12163 
12164  template <typename T>
12165  struct xnor_op : public opr_base<T>
12166  {
12167  typedef typename opr_base<T>::Type Type;
12168  static inline T process(Type t1, Type t2) { return numeric::xnor_opr<T>(t1,t2); }
12169  static inline typename expression_node<T>::node_type type() { return expression_node<T>::e_nor; }
12171  };
12172 
12173  template <typename T>
12174  struct in_op : public opr_base<T>
12175  {
12176  typedef typename opr_base<T>::Type Type;
12177  static inline T process(const T&, const T&) { return std::numeric_limits<T>::quiet_NaN(); }
12178  static inline T process(const std::string& t1, const std::string& t2) { return ((std::string::npos != t2.find(t1)) ? T(1) : T(0)); }
12179  static inline typename expression_node<T>::node_type type() { return expression_node<T>::e_in; }
12180  static inline details::operator_type operation() { return details::e_in; }
12181  };
12182 
12183  template <typename T>
12184  struct like_op : public opr_base<T>
12185  {
12186  typedef typename opr_base<T>::Type Type;
12187  static inline T process(const T&, const T&) { return std::numeric_limits<T>::quiet_NaN(); }
12188  static inline T process(const std::string& t1, const std::string& t2) { return (details::wc_match(t2,t1) ? T(1) : T(0)); }
12191  };
12192 
12193  template <typename T>
12194  struct ilike_op : public opr_base<T>
12195  {
12196  typedef typename opr_base<T>::Type Type;
12197  static inline T process(const T&, const T&) { return std::numeric_limits<T>::quiet_NaN(); }
12198  static inline T process(const std::string& t1, const std::string& t2) { return (details::wc_imatch(t2,t1) ? T(1) : T(0)); }
12201  };
12202 
12203  template <typename T>
12204  struct inrange_op : public opr_base<T>
12205  {
12206  typedef typename opr_base<T>::Type Type;
12207  static inline T process(const T& t0, const T& t1, const T& t2) { return ((t0 <= t1) && (t1 <= t2)) ? T(1) : T(0); }
12208  static inline T process(const std::string& t0, const std::string& t1, const std::string& t2)
12209  {
12210  return ((t0 <= t1) && (t1 <= t2)) ? T(1) : T(0);
12211  }
12214  };
12215 
12216  template <typename T>
12218  {
12219  return n->value();
12220  }
12221 
12222  template <typename T>
12223  inline T value(T* t)
12224  {
12225  return (*t);
12226  }
12227 
12228  template <typename T>
12229  struct vararg_add_op : public opr_base<T>
12230  {
12231  typedef typename opr_base<T>::Type Type;
12232 
12233  template <typename Type,
12234  typename Allocator,
12235  template <typename,typename> class Sequence>
12236  static inline T process(const Sequence<Type,Allocator>& arg_list)
12237  {
12238  switch (arg_list.size())
12239  {
12240  case 0 : return T(0);
12241  case 1 : return process_1(arg_list);
12242  case 2 : return process_2(arg_list);
12243  case 3 : return process_3(arg_list);
12244  case 4 : return process_4(arg_list);
12245  case 5 : return process_5(arg_list);
12246  default :
12247  {
12248  T result = T(0);
12249 
12250  for (std::size_t i = 0; i < arg_list.size(); ++i)
12251  {
12252  result += value(arg_list[i]);
12253  }
12254 
12255  return result;
12256  }
12257  }
12258  }
12259 
12260  template <typename Sequence>
12261  static inline T process_1(const Sequence& arg_list)
12262  {
12263  return value(arg_list[0]);
12264  }
12265 
12266  template <typename Sequence>
12267  static inline T process_2(const Sequence& arg_list)
12268  {
12269  return value(arg_list[0]) + value(arg_list[1]);
12270  }
12271 
12272  template <typename Sequence>
12273  static inline T process_3(const Sequence& arg_list)
12274  {
12275  return value(arg_list[0]) + value(arg_list[1]) +
12276  value(arg_list[2]) ;
12277  }
12278 
12279  template <typename Sequence>
12280  static inline T process_4(const Sequence& arg_list)
12281  {
12282  return value(arg_list[0]) + value(arg_list[1]) +
12283  value(arg_list[2]) + value(arg_list[3]) ;
12284  }
12285 
12286  template <typename Sequence>
12287  static inline T process_5(const Sequence& arg_list)
12288  {
12289  return value(arg_list[0]) + value(arg_list[1]) +
12290  value(arg_list[2]) + value(arg_list[3]) +
12291  value(arg_list[4]) ;
12292  }
12293  };
12294 
12295  template <typename T>
12296  struct vararg_mul_op : public opr_base<T>
12297  {
12298  typedef typename opr_base<T>::Type Type;
12299 
12300  template <typename Type,
12301  typename Allocator,
12302  template <typename,typename> class Sequence>
12303  static inline T process(const Sequence<Type,Allocator>& arg_list)
12304  {
12305  switch (arg_list.size())
12306  {
12307  case 0 : return T(0);
12308  case 1 : return process_1(arg_list);
12309  case 2 : return process_2(arg_list);
12310  case 3 : return process_3(arg_list);
12311  case 4 : return process_4(arg_list);
12312  case 5 : return process_5(arg_list);
12313  default :
12314  {
12315  T result = T(value(arg_list[0]));
12316 
12317  for (std::size_t i = 1; i < arg_list.size(); ++i)
12318  {
12319  result *= value(arg_list[i]);
12320  }
12321 
12322  return result;
12323  }
12324  }
12325  }
12326 
12327  template <typename Sequence>
12328  static inline T process_1(const Sequence& arg_list)
12329  {
12330  return value(arg_list[0]);
12331  }
12332 
12333  template <typename Sequence>
12334  static inline T process_2(const Sequence& arg_list)
12335  {
12336  return value(arg_list[0]) * value(arg_list[1]);
12337  }
12338 
12339  template <typename Sequence>
12340  static inline T process_3(const Sequence& arg_list)
12341  {
12342  return value(arg_list[0]) * value(arg_list[1]) *
12343  value(arg_list[2]) ;
12344  }
12345 
12346  template <typename Sequence>
12347  static inline T process_4(const Sequence& arg_list)
12348  {
12349  return value(arg_list[0]) * value(arg_list[1]) *
12350  value(arg_list[2]) * value(arg_list[3]) ;
12351  }
12352 
12353  template <typename Sequence>
12354  static inline T process_5(const Sequence& arg_list)
12355  {
12356  return value(arg_list[0]) * value(arg_list[1]) *
12357  value(arg_list[2]) * value(arg_list[3]) *
12358  value(arg_list[4]) ;
12359  }
12360  };
12361 
12362  template <typename T>
12363  struct vararg_avg_op : public opr_base<T>
12364  {
12365  typedef typename opr_base<T>::Type Type;
12366 
12367  template <typename Type,
12368  typename Allocator,
12369  template <typename,typename> class Sequence>
12370  static inline T process(const Sequence<Type,Allocator>& arg_list)
12371  {
12372  switch (arg_list.size())
12373  {
12374  case 0 : return T(0);
12375  case 1 : return process_1(arg_list);
12376  case 2 : return process_2(arg_list);
12377  case 3 : return process_3(arg_list);
12378  case 4 : return process_4(arg_list);
12379  case 5 : return process_5(arg_list);
12380  default : return vararg_add_op<T>::process(arg_list) / arg_list.size();
12381  }
12382  }
12383 
12384  template <typename Sequence>
12385  static inline T process_1(const Sequence& arg_list)
12386  {
12387  return value(arg_list[0]);
12388  }
12389 
12390  template <typename Sequence>
12391  static inline T process_2(const Sequence& arg_list)
12392  {
12393  return (value(arg_list[0]) + value(arg_list[1])) / T(2);
12394  }
12395 
12396  template <typename Sequence>
12397  static inline T process_3(const Sequence& arg_list)
12398  {
12399  return (value(arg_list[0]) + value(arg_list[1]) + value(arg_list[2])) / T(3);
12400  }
12401 
12402  template <typename Sequence>
12403  static inline T process_4(const Sequence& arg_list)
12404  {
12405  return (value(arg_list[0]) + value(arg_list[1]) +
12406  value(arg_list[2]) + value(arg_list[3])) / T(4);
12407  }
12408 
12409  template <typename Sequence>
12410  static inline T process_5(const Sequence& arg_list)
12411  {
12412  return (value(arg_list[0]) + value(arg_list[1]) +
12413  value(arg_list[2]) + value(arg_list[3]) +
12414  value(arg_list[4])) / T(5);
12415  }
12416  };
12417 
12418  template <typename T>
12419  struct vararg_min_op : public opr_base<T>
12420  {
12421  typedef typename opr_base<T>::Type Type;
12422 
12423  template <typename Type,
12424  typename Allocator,
12425  template <typename,typename> class Sequence>
12426  static inline T process(const Sequence<Type,Allocator>& arg_list)
12427  {
12428  switch (arg_list.size())
12429  {
12430  case 0 : return T(0);
12431  case 1 : return process_1(arg_list);
12432  case 2 : return process_2(arg_list);
12433  case 3 : return process_3(arg_list);
12434  case 4 : return process_4(arg_list);
12435  case 5 : return process_5(arg_list);
12436  default :
12437  {
12438  T result = T(value(arg_list[0]));
12439 
12440  for (std::size_t i = 1; i < arg_list.size(); ++i)
12441  {
12442  const T v = value(arg_list[i]);
12443 
12444  if (v < result)
12445  result = v;
12446  }
12447 
12448  return result;
12449  }
12450  }
12451  }
12452 
12453  template <typename Sequence>
12454  static inline T process_1(const Sequence& arg_list)
12455  {
12456  return value(arg_list[0]);
12457  }
12458 
12459  template <typename Sequence>
12460  static inline T process_2(const Sequence& arg_list)
12461  {
12462  return std::min<T>(value(arg_list[0]),value(arg_list[1]));
12463  }
12464 
12465  template <typename Sequence>
12466  static inline T process_3(const Sequence& arg_list)
12467  {
12468  return std::min<T>(std::min<T>(value(arg_list[0]),value(arg_list[1])),value(arg_list[2]));
12469  }
12470 
12471  template <typename Sequence>
12472  static inline T process_4(const Sequence& arg_list)
12473  {
12474  return std::min<T>(
12475  std::min<T>(value(arg_list[0]),value(arg_list[1])),
12476  std::min<T>(value(arg_list[2]),value(arg_list[3])));
12477  }
12478 
12479  template <typename Sequence>
12480  static inline T process_5(const Sequence& arg_list)
12481  {
12482  return std::min<T>(
12483  std::min<T>(std::min<T>(value(arg_list[0]),value(arg_list[1])),
12484  std::min<T>(value(arg_list[2]),value(arg_list[3]))),
12485  value(arg_list[4]));
12486  }
12487  };
12488 
12489  template <typename T>
12490  struct vararg_max_op : public opr_base<T>
12491  {
12492  typedef typename opr_base<T>::Type Type;
12493 
12494  template <typename Type,
12495  typename Allocator,
12496  template <typename,typename> class Sequence>
12497  static inline T process(const Sequence<Type,Allocator>& arg_list)
12498  {
12499  switch (arg_list.size())
12500  {
12501  case 0 : return T(0);
12502  case 1 : return process_1(arg_list);
12503  case 2 : return process_2(arg_list);
12504  case 3 : return process_3(arg_list);
12505  case 4 : return process_4(arg_list);
12506  case 5 : return process_5(arg_list);
12507  default :
12508  {
12509  T result = T(value(arg_list[0]));
12510 
12511  for (std::size_t i = 1; i < arg_list.size(); ++i)
12512  {
12513  const T v = value(arg_list[i]);
12514 
12515  if (v > result)
12516  result = v;
12517  }
12518 
12519  return result;
12520  }
12521  }
12522  }
12523 
12524  template <typename Sequence>
12525  static inline T process_1(const Sequence& arg_list)
12526  {
12527  return value(arg_list[0]);
12528  }
12529 
12530  template <typename Sequence>
12531  static inline T process_2(const Sequence& arg_list)
12532  {
12533  return std::max<T>(value(arg_list[0]),value(arg_list[1]));
12534  }
12535 
12536  template <typename Sequence>
12537  static inline T process_3(const Sequence& arg_list)
12538  {
12539  return std::max<T>(std::max<T>(value(arg_list[0]),value(arg_list[1])),value(arg_list[2]));
12540  }
12541 
12542  template <typename Sequence>
12543  static inline T process_4(const Sequence& arg_list)
12544  {
12545  return std::max<T>(
12546  std::max<T>(value(arg_list[0]),value(arg_list[1])),
12547  std::max<T>(value(arg_list[2]),value(arg_list[3])));
12548  }
12549 
12550  template <typename Sequence>
12551  static inline T process_5(const Sequence& arg_list)
12552  {
12553  return std::max<T>(
12554  std::max<T>(std::max<T>(value(arg_list[0]),value(arg_list[1])),
12555  std::max<T>(value(arg_list[2]),value(arg_list[3]))),
12556  value(arg_list[4]));
12557  }
12558  };
12559 
12560  template <typename T>
12561  struct vararg_mand_op : public opr_base<T>
12562  {
12563  typedef typename opr_base<T>::Type Type;
12564 
12565  template <typename Type,
12566  typename Allocator,
12567  template <typename,typename> class Sequence>
12568  static inline T process(const Sequence<Type,Allocator>& arg_list)
12569  {
12570  switch (arg_list.size())
12571  {
12572  case 1 : return process_1(arg_list);
12573  case 2 : return process_2(arg_list);
12574  case 3 : return process_3(arg_list);
12575  case 4 : return process_4(arg_list);
12576  case 5 : return process_5(arg_list);
12577  default :
12578  {
12579  for (std::size_t i = 0; i < arg_list.size(); ++i)
12580  {
12581  if (std::equal_to<T>()(T(0),value(arg_list[i])))
12582  return T(0);
12583  }
12584 
12585  return T(1);
12586  }
12587  }
12588  }
12589 
12590  template <typename Sequence>
12591  static inline T process_1(const Sequence& arg_list)
12592  {
12593  return std::not_equal_to<T>()
12594  (T(0),value(arg_list[0])) ? T(1) : T(0);
12595  }
12596 
12597  template <typename Sequence>
12598  static inline T process_2(const Sequence& arg_list)
12599  {
12600  return (
12601  std::not_equal_to<T>()(T(0),value(arg_list[0])) &&
12602  std::not_equal_to<T>()(T(0),value(arg_list[1]))
12603  ) ? T(1) : T(0);
12604  }
12605 
12606  template <typename Sequence>
12607  static inline T process_3(const Sequence& arg_list)
12608  {
12609  return (
12610  std::not_equal_to<T>()(T(0),value(arg_list[0])) &&
12611  std::not_equal_to<T>()(T(0),value(arg_list[1])) &&
12612  std::not_equal_to<T>()(T(0),value(arg_list[2]))
12613  ) ? T(1) : T(0);
12614  }
12615 
12616  template <typename Sequence>
12617  static inline T process_4(const Sequence& arg_list)
12618  {
12619  return (
12620  std::not_equal_to<T>()(T(0),value(arg_list[0])) &&
12621  std::not_equal_to<T>()(T(0),value(arg_list[1])) &&
12622  std::not_equal_to<T>()(T(0),value(arg_list[2])) &&
12623  std::not_equal_to<T>()(T(0),value(arg_list[3]))
12624  ) ? T(1) : T(0);
12625  }
12626 
12627  template <typename Sequence>
12628  static inline T process_5(const Sequence& arg_list)
12629  {
12630  return (
12631  std::not_equal_to<T>()(T(0),value(arg_list[0])) &&
12632  std::not_equal_to<T>()(T(0),value(arg_list[1])) &&
12633  std::not_equal_to<T>()(T(0),value(arg_list[2])) &&
12634  std::not_equal_to<T>()(T(0),value(arg_list[3])) &&
12635  std::not_equal_to<T>()(T(0),value(arg_list[4]))
12636  ) ? T(1) : T(0);
12637  }
12638  };
12639 
12640  template <typename T>
12641  struct vararg_mor_op : public opr_base<T>
12642  {
12643  typedef typename opr_base<T>::Type Type;
12644 
12645  template <typename Type,
12646  typename Allocator,
12647  template <typename,typename> class Sequence>
12648  static inline T process(const Sequence<Type,Allocator>& arg_list)
12649  {
12650  switch (arg_list.size())
12651  {
12652  case 1 : return process_1(arg_list);
12653  case 2 : return process_2(arg_list);
12654  case 3 : return process_3(arg_list);
12655  case 4 : return process_4(arg_list);
12656  case 5 : return process_5(arg_list);
12657  default :
12658  {
12659  for (std::size_t i = 0; i < arg_list.size(); ++i)
12660  {
12661  if (std::not_equal_to<T>()(T(0),value(arg_list[i])))
12662  return T(1);
12663  }
12664 
12665  return T(0);
12666  }
12667  }
12668  }
12669 
12670  template <typename Sequence>
12671  static inline T process_1(const Sequence& arg_list)
12672  {
12673  return std::not_equal_to<T>()
12674  (T(0),value(arg_list[0])) ? T(1) : T(0);
12675  }
12676 
12677  template <typename Sequence>
12678  static inline T process_2(const Sequence& arg_list)
12679  {
12680  return (
12681  std::not_equal_to<T>()(T(0),value(arg_list[0])) ||
12682  std::not_equal_to<T>()(T(0),value(arg_list[1]))
12683  ) ? T(1) : T(0);
12684  }
12685 
12686  template <typename Sequence>
12687  static inline T process_3(const Sequence& arg_list)
12688  {
12689  return (
12690  std::not_equal_to<T>()(T(0),value(arg_list[0])) ||
12691  std::not_equal_to<T>()(T(0),value(arg_list[1])) ||
12692  std::not_equal_to<T>()(T(0),value(arg_list[2]))
12693  ) ? T(1) : T(0);
12694  }
12695 
12696  template <typename Sequence>
12697  static inline T process_4(const Sequence& arg_list)
12698  {
12699  return (
12700  std::not_equal_to<T>()(T(0),value(arg_list[0])) ||
12701  std::not_equal_to<T>()(T(0),value(arg_list[1])) ||
12702  std::not_equal_to<T>()(T(0),value(arg_list[2])) ||
12703  std::not_equal_to<T>()(T(0),value(arg_list[3]))
12704  ) ? T(1) : T(0);
12705  }
12706 
12707  template <typename Sequence>
12708  static inline T process_5(const Sequence& arg_list)
12709  {
12710  return (
12711  std::not_equal_to<T>()(T(0),value(arg_list[0])) ||
12712  std::not_equal_to<T>()(T(0),value(arg_list[1])) ||
12713  std::not_equal_to<T>()(T(0),value(arg_list[2])) ||
12714  std::not_equal_to<T>()(T(0),value(arg_list[3])) ||
12715  std::not_equal_to<T>()(T(0),value(arg_list[4]))
12716  ) ? T(1) : T(0);
12717  }
12718  };
12719 
12720  template <typename T>
12721  struct vararg_multi_op : public opr_base<T>
12722  {
12723  typedef typename opr_base<T>::Type Type;
12724 
12725  template <typename Type,
12726  typename Allocator,
12727  template <typename,typename> class Sequence>
12728  static inline T process(const Sequence<Type,Allocator>& arg_list)
12729  {
12730  switch (arg_list.size())
12731  {
12732  case 0 : return std::numeric_limits<T>::quiet_NaN();
12733  case 1 : return process_1(arg_list);
12734  case 2 : return process_2(arg_list);
12735  case 3 : return process_3(arg_list);
12736  case 4 : return process_4(arg_list);
12737  case 5 : return process_5(arg_list);
12738  case 6 : return process_6(arg_list);
12739  case 7 : return process_7(arg_list);
12740  case 8 : return process_8(arg_list);
12741  default :
12742  {
12743  for (std::size_t i = 0; i < (arg_list.size() - 1); ++i)
12744  {
12745  value(arg_list[i]);
12746  }
12747 
12748  return value(arg_list.back());
12749  }
12750  }
12751  }
12752 
12753  template <typename Sequence>
12754  static inline T process_1(const Sequence& arg_list)
12755  {
12756  return value(arg_list[0]);
12757  }
12758 
12759  template <typename Sequence>
12760  static inline T process_2(const Sequence& arg_list)
12761  {
12762  value(arg_list[0]);
12763  return value(arg_list[1]);
12764  }
12765 
12766  template <typename Sequence>
12767  static inline T process_3(const Sequence& arg_list)
12768  {
12769  value(arg_list[0]);
12770  value(arg_list[1]);
12771  return value(arg_list[2]);
12772  }
12773 
12774  template <typename Sequence>
12775  static inline T process_4(const Sequence& arg_list)
12776  {
12777  value(arg_list[0]);
12778  value(arg_list[1]);
12779  value(arg_list[2]);
12780  return value(arg_list[3]);
12781  }
12782 
12783  template <typename Sequence>
12784  static inline T process_5(const Sequence& arg_list)
12785  {
12786  value(arg_list[0]);
12787  value(arg_list[1]);
12788  value(arg_list[2]);
12789  value(arg_list[3]);
12790  return value(arg_list[4]);
12791  }
12792 
12793  template <typename Sequence>
12794  static inline T process_6(const Sequence& arg_list)
12795  {
12796  value(arg_list[0]);
12797  value(arg_list[1]);
12798  value(arg_list[2]);
12799  value(arg_list[3]);
12800  value(arg_list[4]);
12801  return value(arg_list[5]);
12802  }
12803 
12804  template <typename Sequence>
12805  static inline T process_7(const Sequence& arg_list)
12806  {
12807  value(arg_list[0]);
12808  value(arg_list[1]);
12809  value(arg_list[2]);
12810  value(arg_list[3]);
12811  value(arg_list[4]);
12812  value(arg_list[5]);
12813  return value(arg_list[6]);
12814  }
12815 
12816  template <typename Sequence>
12817  static inline T process_8(const Sequence& arg_list)
12818  {
12819  value(arg_list[0]);
12820  value(arg_list[1]);
12821  value(arg_list[2]);
12822  value(arg_list[3]);
12823  value(arg_list[4]);
12824  value(arg_list[5]);
12825  value(arg_list[6]);
12826  return value(arg_list[7]);
12827  }
12828  };
12829 
12830  template <typename T>
12831  struct vec_add_op
12832  {
12834 
12835  static inline T process(const ivector_ptr v)
12836  {
12837  const T* vec = v->vec()->vds().data();
12838  const std::size_t vec_size = v->vec()->vds().size();
12839 
12840  loop_unroll::details lud(vec_size);
12841 
12842  if (vec_size <= static_cast<std::size_t>(lud.batch_size))
12843  {
12844  T result = T(0);
12845  int i = 0;
12846 
12848  switch (vec_size)
12849  {
12850  #define case_stmt(N) \
12851  case N : result += vec[i++]; \
12852 
12853  #ifndef exprtk_disable_superscalar_unroll
12854  case_stmt(16) case_stmt(15)
12855  case_stmt(14) case_stmt(13)
12856  case_stmt(12) case_stmt(11)
12857  case_stmt(10) case_stmt( 9)
12858  case_stmt( 8) case_stmt( 7)
12859  case_stmt( 6) case_stmt( 5)
12860  #endif
12861  case_stmt( 4) case_stmt( 3)
12862  case_stmt( 2) case_stmt( 1)
12863  }
12865 
12866  #undef case_stmt
12867 
12868  return result;
12869  }
12870 
12871  T r[] = {
12872  T(0), T(0), T(0), T(0), T(0), T(0), T(0), T(0),
12873  T(0), T(0), T(0), T(0), T(0), T(0), T(0), T(0)
12874  };
12875 
12876  const T* upper_bound = vec + lud.upper_bound;
12877 
12878  while (vec < upper_bound)
12879  {
12880  #define exprtk_loop(N) \
12881  r[N] += vec[N]; \
12882 
12883  exprtk_loop( 0) exprtk_loop( 1)
12884  exprtk_loop( 2) exprtk_loop( 3)
12885  #ifndef exprtk_disable_superscalar_unroll
12886  exprtk_loop( 4) exprtk_loop( 5)
12887  exprtk_loop( 6) exprtk_loop( 7)
12888  exprtk_loop( 8) exprtk_loop( 9)
12889  exprtk_loop(10) exprtk_loop(11)
12890  exprtk_loop(12) exprtk_loop(13)
12891  exprtk_loop(14) exprtk_loop(15)
12892  #endif
12893 
12894  vec += lud.batch_size;
12895  }
12896 
12897  int i = 0;
12898 
12900  switch (lud.remainder)
12901  {
12902  #define case_stmt(N) \
12903  case N : r[0] += vec[i++]; \
12904 
12905  #ifndef exprtk_disable_superscalar_unroll
12906  case_stmt(15) case_stmt(14)
12907  case_stmt(13) case_stmt(12)
12908  case_stmt(11) case_stmt(10)
12909  case_stmt( 9) case_stmt( 8)
12910  case_stmt( 7) case_stmt( 6)
12911  case_stmt( 5) case_stmt( 4)
12912  #endif
12913  case_stmt( 3) case_stmt( 2)
12914  case_stmt( 1)
12915  }
12917 
12918  #undef exprtk_loop
12919  #undef case_stmt
12920 
12921  return (r[ 0] + r[ 1] + r[ 2] + r[ 3])
12922  #ifndef exprtk_disable_superscalar_unroll
12923  + (r[ 4] + r[ 5] + r[ 6] + r[ 7])
12924  + (r[ 8] + r[ 9] + r[10] + r[11])
12925  + (r[12] + r[13] + r[14] + r[15])
12926  #endif
12927  ;
12928  }
12929  };
12930 
12931  template <typename T>
12932  struct vec_mul_op
12933  {
12935 
12936  static inline T process(const ivector_ptr v)
12937  {
12938  const T* vec = v->vec()->vds().data();
12939  const std::size_t vec_size = v->vec()->vds().size();
12940 
12941  loop_unroll::details lud(vec_size);
12942 
12943  if (vec_size <= static_cast<std::size_t>(lud.batch_size))
12944  {
12945  T result = T(1);
12946  int i = 0;
12947 
12949  switch (vec_size)
12950  {
12951  #define case_stmt(N) \
12952  case N : result *= vec[i++]; \
12953 
12954  #ifndef exprtk_disable_superscalar_unroll
12955  case_stmt(16) case_stmt(15)
12956  case_stmt(14) case_stmt(13)
12957  case_stmt(12) case_stmt(11)
12958  case_stmt(10) case_stmt( 9)
12959  case_stmt( 8) case_stmt( 7)
12960  case_stmt( 6) case_stmt( 5)
12961  #endif
12962  case_stmt( 4) case_stmt( 3)
12963  case_stmt( 2) case_stmt( 1)
12964  }
12966 
12967  #undef case_stmt
12968 
12969  return result;
12970  }
12971 
12972  T r[] = {
12973  T(1), T(1), T(1), T(1), T(1), T(1), T(1), T(1),
12974  T(1), T(1), T(1), T(1), T(1), T(1), T(1), T(1)
12975  };
12976 
12977  const T* upper_bound = vec + lud.upper_bound;
12978 
12979  while (vec < upper_bound)
12980  {
12981  #define exprtk_loop(N) \
12982  r[N] *= vec[N]; \
12983 
12984  exprtk_loop( 0) exprtk_loop( 1)
12985  exprtk_loop( 2) exprtk_loop( 3)
12986  #ifndef exprtk_disable_superscalar_unroll
12987  exprtk_loop( 4) exprtk_loop( 5)
12988  exprtk_loop( 6) exprtk_loop( 7)
12989  exprtk_loop( 8) exprtk_loop( 9)
12990  exprtk_loop(10) exprtk_loop(11)
12991  exprtk_loop(12) exprtk_loop(13)
12992  exprtk_loop(14) exprtk_loop(15)
12993  #endif
12994 
12995  vec += lud.batch_size;
12996  }
12997 
12998  int i = 0;
12999 
13001  switch (lud.remainder)
13002  {
13003  #define case_stmt(N) \
13004  case N : r[0] *= vec[i++]; \
13005 
13006  #ifndef exprtk_disable_superscalar_unroll
13007  case_stmt(15) case_stmt(14)
13008  case_stmt(13) case_stmt(12)
13009  case_stmt(11) case_stmt(10)
13010  case_stmt( 9) case_stmt( 8)
13011  case_stmt( 7) case_stmt( 6)
13012  case_stmt( 5) case_stmt( 4)
13013  #endif
13014  case_stmt( 3) case_stmt( 2)
13015  case_stmt( 1)
13016  }
13018 
13019  #undef exprtk_loop
13020  #undef case_stmt
13021 
13022  return (r[ 0] * r[ 1] * r[ 2] * r[ 3])
13023  #ifndef exprtk_disable_superscalar_unroll
13024  + (r[ 4] * r[ 5] * r[ 6] * r[ 7])
13025  + (r[ 8] * r[ 9] * r[10] * r[11])
13026  + (r[12] * r[13] * r[14] * r[15])
13027  #endif
13028  ;
13029  }
13030  };
13031 
13032  template <typename T>
13033  struct vec_avg_op
13034  {
13036 
13037  static inline T process(const ivector_ptr v)
13038  {
13039  const std::size_t vec_size = v->vec()->vds().size();
13040 
13041  return vec_add_op<T>::process(v) / vec_size;
13042  }
13043  };
13044 
13045  template <typename T>
13046  struct vec_min_op
13047  {
13049 
13050  static inline T process(const ivector_ptr v)
13051  {
13052  const T* vec = v->vec()->vds().data();
13053  const std::size_t vec_size = v->vec()->vds().size();
13054 
13055  T result = vec[0];
13056 
13057  for (std::size_t i = 1; i < vec_size; ++i)
13058  {
13059  T v_i = vec[i];
13060 
13061  if (v_i < result)
13062  result = v_i;
13063  }
13064 
13065  return result;
13066  }
13067  };
13068 
13069  template <typename T>
13070  struct vec_max_op
13071  {
13073 
13074  static inline T process(const ivector_ptr v)
13075  {
13076  const T* vec = v->vec()->vds().data();
13077  const std::size_t vec_size = v->vec()->vds().size();
13078 
13079  T result = vec[0];
13080 
13081  for (std::size_t i = 1; i < vec_size; ++i)
13082  {
13083  T v_i = vec[i];
13084 
13085  if (v_i > result)
13086  result = v_i;
13087  }
13088 
13089  return result;
13090  }
13091  };
13092 
13093  template <typename T>
13094  class vov_base_node : public expression_node<T>
13095  {
13096  public:
13097 
13098  virtual ~vov_base_node()
13099  {}
13100 
13101  inline virtual operator_type operation() const
13102  {
13103  return details::e_default;
13104  }
13105 
13106  virtual const T& v0() const = 0;
13107 
13108  virtual const T& v1() const = 0;
13109  };
13110 
13111  template <typename T>
13112  class cov_base_node : public expression_node<T>
13113  {
13114  public:
13115 
13116  virtual ~cov_base_node()
13117  {}
13118 
13119  inline virtual operator_type operation() const
13120  {
13121  return details::e_default;
13122  }
13123 
13124  virtual const T c() const = 0;
13125 
13126  virtual const T& v() const = 0;
13127  };
13128 
13129  template <typename T>
13130  class voc_base_node : public expression_node<T>
13131  {
13132  public:
13133 
13134  virtual ~voc_base_node()
13135  {}
13136 
13137  inline virtual operator_type operation() const
13138  {
13139  return details::e_default;
13140  }
13141 
13142  virtual const T c() const = 0;
13143 
13144  virtual const T& v() const = 0;
13145  };
13146 
13147  template <typename T>
13148  class vob_base_node : public expression_node<T>
13149  {
13150  public:
13151 
13152  virtual ~vob_base_node()
13153  {}
13154 
13155  virtual const T& v() const = 0;
13156  };
13157 
13158  template <typename T>
13159  class bov_base_node : public expression_node<T>
13160  {
13161  public:
13162 
13163  virtual ~bov_base_node()
13164  {}
13165 
13166  virtual const T& v() const = 0;
13167  };
13168 
13169  template <typename T>
13170  class cob_base_node : public expression_node<T>
13171  {
13172  public:
13173 
13174  virtual ~cob_base_node()
13175  {}
13176 
13177  inline virtual operator_type operation() const
13178  {
13179  return details::e_default;
13180  }
13181 
13182  virtual const T c() const = 0;
13183 
13184  virtual void set_c(const T) = 0;
13185 
13186  virtual expression_node<T>* move_branch(const std::size_t& index) = 0;
13187  };
13188 
13189  template <typename T>
13190  class boc_base_node : public expression_node<T>
13191  {
13192  public:
13193 
13194  virtual ~boc_base_node()
13195  {}
13196 
13197  inline virtual operator_type operation() const
13198  {
13199  return details::e_default;
13200  }
13201 
13202  virtual const T c() const = 0;
13203 
13204  virtual void set_c(const T) = 0;
13205 
13206  virtual expression_node<T>* move_branch(const std::size_t& index) = 0;
13207  };
13208 
13209  template <typename T>
13210  class uv_base_node : public expression_node<T>
13211  {
13212  public:
13213 
13214  virtual ~uv_base_node()
13215  {}
13216 
13217  inline virtual operator_type operation() const
13218  {
13219  return details::e_default;
13220  }
13221 
13222  virtual const T& v() const = 0;
13223  };
13224 
13225  template <typename T>
13226  class sos_base_node : public expression_node<T>
13227  {
13228  public:
13229 
13230  virtual ~sos_base_node()
13231  {}
13232 
13233  inline virtual operator_type operation() const
13234  {
13235  return details::e_default;
13236  }
13237  };
13238 
13239  template <typename T>
13241  {
13242  public:
13243 
13245  {}
13246 
13247  inline virtual operator_type operation() const
13248  {
13249  return details::e_default;
13250  }
13251  };
13252 
13253  template <typename T>
13255  {
13256  public:
13257 
13259  {}
13260 
13261  virtual std::string type_id() const = 0;
13262  };
13263 
13264  template <typename T>
13266  {
13267  public:
13268 
13270  {}
13271 
13272  virtual std::string type_id() const = 0;
13273  };
13274 
13275  template <typename T, typename Operation>
13277  {
13278  public:
13279 
13281  typedef Operation operation_t;
13282 
13283  explicit unary_variable_node(const T& var)
13284  : v_(var)
13285  {}
13286 
13287  inline T value() const
13288  {
13289  return Operation::process(v_);
13290  }
13291 
13292  inline typename expression_node<T>::node_type type() const
13293  {
13294  return Operation::type();
13295  }
13296 
13297  inline operator_type operation() const
13298  {
13299  return Operation::operation();
13300  }
13301 
13302  inline const T& v() const
13303  {
13304  return v_;
13305  }
13306 
13307  private:
13308 
13311 
13312  const T& v_;
13313  };
13314 
13315  template <typename T>
13316  class uvouv_node : public expression_node<T>
13317  {
13318  public:
13319 
13320  // UOpr1(v0) Op UOpr2(v1)
13321 
13324  typedef typename functor_t::bfunc_t bfunc_t;
13325  typedef typename functor_t::ufunc_t ufunc_t;
13326 
13327  explicit uvouv_node(const T& var0,const T& var1,
13328  ufunc_t uf0, ufunc_t uf1, bfunc_t bf)
13329  : v0_(var0),
13330  v1_(var1),
13331  u0_(uf0 ),
13332  u1_(uf1 ),
13333  f_ (bf )
13334  {}
13335 
13336  inline T value() const
13337  {
13338  return f_(u0_(v0_),u1_(v1_));
13339  }
13340 
13341  inline typename expression_node<T>::node_type type() const
13342  {
13344  }
13345 
13346  inline operator_type operation() const
13347  {
13348  return details::e_default;
13349  }
13350 
13351  inline const T& v0()
13352  {
13353  return v0_;
13354  }
13355 
13356  inline const T& v1()
13357  {
13358  return v1_;
13359  }
13360 
13361  inline ufunc_t u0()
13362  {
13363  return u0_;
13364  }
13365 
13366  inline ufunc_t u1()
13367  {
13368  return u1_;
13369  }
13370 
13371  inline ufunc_t f()
13372  {
13373  return f_;
13374  }
13375 
13376  private:
13377 
13380 
13381  const T& v0_;
13382  const T& v1_;
13383  const ufunc_t u0_;
13384  const ufunc_t u1_;
13385  const bfunc_t f_;
13386  };
13387 
13388  template <typename T, typename Operation>
13390  {
13391  public:
13392 
13394  typedef Operation operation_t;
13395 
13397  : branch_(brnch),
13399  {}
13400 
13402  {
13403  if (branch_ && branch_deletable_)
13404  {
13406  }
13407  }
13408 
13409  inline T value() const
13410  {
13411  return Operation::process(branch_->value());
13412  }
13413 
13414  inline typename expression_node<T>::node_type type() const
13415  {
13416  return Operation::type();
13417  }
13418 
13419  inline operator_type operation() const
13420  {
13421  return Operation::operation();
13422  }
13423 
13424  inline expression_node<T>* branch(const std::size_t&) const
13425  {
13426  return branch_;
13427  }
13428 
13429  inline void release()
13430  {
13431  branch_deletable_ = false;
13432  }
13433 
13434  private:
13435 
13438 
13441  };
13442 
13443  template <typename T> struct is_const { enum {result = 0}; };
13444  template <typename T> struct is_const <const T> { enum {result = 1}; };
13445  template <typename T> struct is_const_ref { enum {result = 0}; };
13446  template <typename T> struct is_const_ref <const T&> { enum {result = 1}; };
13447  template <typename T> struct is_ref { enum {result = 0}; };
13448  template <typename T> struct is_ref<T&> { enum {result = 1}; };
13449  template <typename T> struct is_ref<const T&> { enum {result = 0}; };
13450 
13451  template <std::size_t State>
13452  struct param_to_str { static std::string result() { static const std::string r("v"); return r; } };
13453 
13454  template <>
13455  struct param_to_str<0> { static std::string result() { static const std::string r("c"); return r; } };
13456 
13457  #define exprtk_crtype(Type) \
13458  param_to_str<is_const_ref< Type >::result>::result() \
13459 
13460  template <typename T>
13462  {
13464  typedef typename functor_t::bfunc_t bfunc_t;
13465 
13466  struct mode0
13467  {
13468  static inline T process(const T& t0, const T& t1, const T& t2, const bfunc_t bf0, const bfunc_t bf1)
13469  {
13470  // (T0 o0 T1) o1 T2
13471  return bf1(bf0(t0,t1),t2);
13472  }
13473 
13474  template <typename T0, typename T1, typename T2>
13475  static inline std::string id()
13476  {
13477  static const std::string result = "(" + exprtk_crtype(T0) + "o" +
13478  exprtk_crtype(T1) + ")o(" +
13479  exprtk_crtype(T2) + ")" ;
13480  return result;
13481  }
13482  };
13483 
13484  struct mode1
13485  {
13486  static inline T process(const T& t0, const T& t1, const T& t2, const bfunc_t bf0, const bfunc_t bf1)
13487  {
13488  // T0 o0 (T1 o1 T2)
13489  return bf0(t0,bf1(t1,t2));
13490  }
13491 
13492  template <typename T0, typename T1, typename T2>
13493  static inline std::string id()
13494  {
13495  static const std::string result = "(" + exprtk_crtype(T0) + ")o(" +
13496  exprtk_crtype(T1) + "o" +
13497  exprtk_crtype(T2) + ")" ;
13498  return result;
13499  }
13500  };
13501  };
13502 
13503  template <typename T>
13505  {
13507  typedef typename functor_t::bfunc_t bfunc_t;
13508 
13509  struct mode0
13510  {
13511  static inline T process(const T& t0, const T& t1,
13512  const T& t2, const T& t3,
13513  const bfunc_t bf0, const bfunc_t bf1, const bfunc_t bf2)
13514  {
13515  // (T0 o0 T1) o1 (T2 o2 T3)
13516  return bf1(bf0(t0,t1),bf2(t2,t3));
13517  }
13518 
13519  template <typename T0, typename T1, typename T2, typename T3>
13520  static inline std::string id()
13521  {
13522  static const std::string result = "(" + exprtk_crtype(T0) + "o" +
13523  exprtk_crtype(T1) + ")o" +
13524  "(" + exprtk_crtype(T2) + "o" +
13525  exprtk_crtype(T3) + ")" ;
13526  return result;
13527  }
13528  };
13529 
13530  struct mode1
13531  {
13532  static inline T process(const T& t0, const T& t1,
13533  const T& t2, const T& t3,
13534  const bfunc_t bf0, const bfunc_t bf1, const bfunc_t bf2)
13535  {
13536  // (T0 o0 (T1 o1 (T2 o2 T3))
13537  return bf0(t0,bf1(t1,bf2(t2,t3)));
13538  }
13539  template <typename T0, typename T1, typename T2, typename T3>
13540  static inline std::string id()
13541  {
13542  static const std::string result = "(" + exprtk_crtype(T0) + ")o((" +
13543  exprtk_crtype(T1) + ")o(" +
13544  exprtk_crtype(T2) + "o" +
13545  exprtk_crtype(T3) + "))" ;
13546  return result;
13547  }
13548  };
13549 
13550  struct mode2
13551  {
13552  static inline T process(const T& t0, const T& t1,
13553  const T& t2, const T& t3,
13554  const bfunc_t bf0, const bfunc_t bf1, const bfunc_t bf2)
13555  {
13556  // (T0 o0 ((T1 o1 T2) o2 T3)
13557  return bf0(t0,bf2(bf1(t1,t2),t3));
13558  }
13559 
13560  template <typename T0, typename T1, typename T2, typename T3>
13561  static inline std::string id()
13562  {
13563  static const std::string result = "(" + exprtk_crtype(T0) + ")o((" +
13564  exprtk_crtype(T1) + "o" +
13565  exprtk_crtype(T2) + ")o(" +
13566  exprtk_crtype(T3) + "))" ;
13567  return result;
13568  }
13569  };
13570 
13571  struct mode3
13572  {
13573  static inline T process(const T& t0, const T& t1,
13574  const T& t2, const T& t3,
13575  const bfunc_t bf0, const bfunc_t bf1, const bfunc_t bf2)
13576  {
13577  // (((T0 o0 T1) o1 T2) o2 T3)
13578  return bf2(bf1(bf0(t0,t1),t2),t3);
13579  }
13580 
13581  template <typename T0, typename T1, typename T2, typename T3>
13582  static inline std::string id()
13583  {
13584  static const std::string result = "((" + exprtk_crtype(T0) + "o" +
13585  exprtk_crtype(T1) + ")o(" +
13586  exprtk_crtype(T2) + "))o(" +
13587  exprtk_crtype(T3) + ")";
13588  return result;
13589  }
13590  };
13591 
13592  struct mode4
13593  {
13594  static inline T process(const T& t0, const T& t1,
13595  const T& t2, const T& t3,
13596  const bfunc_t bf0, const bfunc_t bf1, const bfunc_t bf2)
13597  {
13598  // ((T0 o0 (T1 o1 T2)) o2 T3
13599  return bf2(bf0(t0,bf1(t1,t2)),t3);
13600  }
13601 
13602  template <typename T0, typename T1, typename T2, typename T3>
13603  static inline std::string id()
13604  {
13605  static const std::string result = "((" + exprtk_crtype(T0) + ")o(" +
13606  exprtk_crtype(T1) + "o" +
13607  exprtk_crtype(T2) + "))o(" +
13608  exprtk_crtype(T3) + ")" ;
13609  return result;
13610  }
13611  };
13612  };
13613 
13614  #undef exprtk_crtype
13615 
13616  template <typename T, typename T0, typename T1>
13617  struct nodetype_T0oT1 { static const typename expression_node<T>::node_type result; };
13618  template <typename T, typename T0, typename T1>
13620 
13621  #define synthesis_node_type_define(T0_,T1_,v_) \
13622  template <typename T, typename T0, typename T1> \
13623  struct nodetype_T0oT1<T,T0_,T1_> { static const typename expression_node<T>::node_type result; }; \
13624  template <typename T, typename T0, typename T1> \
13625  const typename expression_node<T>::node_type nodetype_T0oT1<T,T0_,T1_>::result = expression_node<T>:: v_; \
13626 
13627  synthesis_node_type_define(const T0&,const T1&, e_vov)
13628  synthesis_node_type_define(const T0&,const T1 , e_voc)
13629  synthesis_node_type_define(const T0 ,const T1&, e_cov)
13630  synthesis_node_type_define( T0&, T1&,e_none)
13631  synthesis_node_type_define(const T0 ,const T1 ,e_none)
13632  synthesis_node_type_define( T0&,const T1 ,e_none)
13633  synthesis_node_type_define(const T0 , T1&,e_none)
13634  synthesis_node_type_define(const T0&, T1&,e_none)
13635  synthesis_node_type_define( T0&,const T1&,e_none)
13636  #undef synthesis_node_type_define
13637 
13638  template <typename T, typename T0, typename T1, typename T2>
13639  struct nodetype_T0oT1oT2 { static const typename expression_node<T>::node_type result; };
13640  template <typename T, typename T0, typename T1, typename T2>
13642 
13643  #define synthesis_node_type_define(T0_,T1_,T2_,v_) \
13644  template <typename T, typename T0, typename T1, typename T2> \
13645  struct nodetype_T0oT1oT2<T,T0_,T1_,T2_> { static const typename expression_node<T>::node_type result; }; \
13646  template <typename T, typename T0, typename T1, typename T2> \
13647  const typename expression_node<T>::node_type nodetype_T0oT1oT2<T,T0_,T1_,T2_>::result = expression_node<T>:: v_; \
13648 
13649  synthesis_node_type_define(const T0&,const T1&,const T2&, e_vovov)
13650  synthesis_node_type_define(const T0&,const T1&,const T2 , e_vovoc)
13651  synthesis_node_type_define(const T0&,const T1 ,const T2&, e_vocov)
13652  synthesis_node_type_define(const T0 ,const T1&,const T2&, e_covov)
13653  synthesis_node_type_define(const T0 ,const T1&,const T2 , e_covoc)
13654  synthesis_node_type_define(const T0 ,const T1 ,const T2 , e_none )
13655  synthesis_node_type_define(const T0 ,const T1 ,const T2&, e_none )
13656  synthesis_node_type_define(const T0&,const T1 ,const T2 , e_none )
13657  synthesis_node_type_define( T0&, T1&, T2&, e_none )
13658  #undef synthesis_node_type_define
13659 
13660  template <typename T, typename T0, typename T1, typename T2, typename T3>
13661  struct nodetype_T0oT1oT2oT3 { static const typename expression_node<T>::node_type result; };
13662  template <typename T, typename T0, typename T1, typename T2, typename T3>
13664 
13665  #define synthesis_node_type_define(T0_,T1_,T2_,T3_,v_) \
13666  template <typename T, typename T0, typename T1, typename T2, typename T3> \
13667  struct nodetype_T0oT1oT2oT3<T,T0_,T1_,T2_,T3_> { static const typename expression_node<T>::node_type result; }; \
13668  template <typename T, typename T0, typename T1, typename T2, typename T3> \
13669  const typename expression_node<T>::node_type nodetype_T0oT1oT2oT3<T,T0_,T1_,T2_,T3_>::result = expression_node<T>:: v_; \
13670 
13671  synthesis_node_type_define(const T0&,const T1&,const T2&, const T3&,e_vovovov)
13672  synthesis_node_type_define(const T0&,const T1&,const T2&, const T3 ,e_vovovoc)
13673  synthesis_node_type_define(const T0&,const T1&,const T2 , const T3&,e_vovocov)
13674  synthesis_node_type_define(const T0&,const T1 ,const T2&, const T3&,e_vocovov)
13675  synthesis_node_type_define(const T0 ,const T1&,const T2&, const T3&,e_covovov)
13676  synthesis_node_type_define(const T0 ,const T1&,const T2 , const T3&,e_covocov)
13677  synthesis_node_type_define(const T0&,const T1 ,const T2&, const T3 ,e_vocovoc)
13678  synthesis_node_type_define(const T0 ,const T1&,const T2&, const T3 ,e_covovoc)
13679  synthesis_node_type_define(const T0&,const T1 ,const T2 , const T3&,e_vococov)
13680  synthesis_node_type_define(const T0 ,const T1 ,const T2 , const T3 ,e_none )
13681  synthesis_node_type_define(const T0 ,const T1 ,const T2 , const T3&,e_none )
13682  synthesis_node_type_define(const T0 ,const T1 ,const T2&, const T3 ,e_none )
13683  synthesis_node_type_define(const T0 ,const T1&,const T2 , const T3 ,e_none )
13684  synthesis_node_type_define(const T0&,const T1 ,const T2 , const T3 ,e_none )
13685  synthesis_node_type_define(const T0 ,const T1 ,const T2&, const T3&,e_none )
13686  synthesis_node_type_define(const T0&,const T1&,const T2 , const T3 ,e_none )
13687  #undef synthesis_node_type_define
13688 
13689  template <typename T, typename T0, typename T1>
13690  class T0oT1 : public expression_node<T>
13691  {
13692  public:
13693 
13695  typedef typename functor_t::bfunc_t bfunc_t;
13696  typedef T value_type;
13698 
13699  T0oT1(T0 p0, T1 p1, const bfunc_t p2)
13700  : t0_(p0),
13701  t1_(p1),
13702  f_ (p2)
13703  {}
13704 
13705  inline typename expression_node<T>::node_type type() const
13706  {
13707  static const typename expression_node<T>::node_type result = nodetype_T0oT1<T,T0,T1>::result;
13708  return result;
13709  }
13710 
13711  inline operator_type operation() const
13712  {
13713  return e_default;
13714  }
13715 
13716  inline T value() const
13717  {
13718  return f_(t0_,t1_);
13719  }
13720 
13721  inline T0 t0() const
13722  {
13723  return t0_;
13724  }
13725 
13726  inline T1 t1() const
13727  {
13728  return t1_;
13729  }
13730 
13731  inline bfunc_t f() const
13732  {
13733  return f_;
13734  }
13735 
13736  template <typename Allocator>
13737  static inline expression_node<T>* allocate(Allocator& allocator,
13738  T0 p0, T1 p1,
13739  bfunc_t p2)
13740  {
13741  return allocator
13742  .template allocate_type<node_type,T0,T1,bfunc_t&>
13743  (p0, p1, p2);
13744  }
13745 
13746  private:
13747 
13749  T0oT1<T,T0,T1>& operator=(T0oT1<T,T0,T1>&) { return (*this); }
13750 
13751  T0 t0_;
13752  T1 t1_;
13753  const bfunc_t f_;
13754  };
13755 
13756  template <typename T, typename T0, typename T1, typename T2, typename ProcessMode>
13757  class T0oT1oT2 : public T0oT1oT2_base_node<T>
13758  {
13759  public:
13760 
13762  typedef typename functor_t::bfunc_t bfunc_t;
13763  typedef T value_type;
13765  typedef ProcessMode process_mode_t;
13766 
13767  T0oT1oT2(T0 p0, T1 p1, T2 p2, const bfunc_t p3, const bfunc_t p4)
13768  : t0_(p0),
13769  t1_(p1),
13770  t2_(p2),
13771  f0_(p3),
13772  f1_(p4)
13773  {}
13774 
13775  inline typename expression_node<T>::node_type type() const
13776  {
13778  return result;
13779  }
13780 
13781  inline operator_type operation() const
13782  {
13783  return e_default;
13784  }
13785 
13786  inline T value() const
13787  {
13789  }
13790 
13791  inline T0 t0() const
13792  {
13793  return t0_;
13794  }
13795 
13796  inline T1 t1() const
13797  {
13798  return t1_;
13799  }
13800 
13801  inline T2 t2() const
13802  {
13803  return t2_;
13804  }
13805 
13806  bfunc_t f0() const
13807  {
13808  return f0_;
13809  }
13810 
13811  bfunc_t f1() const
13812  {
13813  return f1_;
13814  }
13815 
13816  std::string type_id() const
13817  {
13818  return id();
13819  }
13820 
13821  static inline std::string id()
13822  {
13823  return process_mode_t::template id<T0,T1,T2>();
13824  }
13825 
13826  template <typename Allocator>
13827  static inline expression_node<T>* allocate(Allocator& allocator, T0 p0, T1 p1, T2 p2, bfunc_t p3, bfunc_t p4)
13828  {
13829  return allocator
13830  .template allocate_type<node_type,T0,T1,T2,bfunc_t,bfunc_t>
13831  (p0, p1, p2, p3, p4);
13832  }
13833 
13834  private:
13835 
13837  node_type& operator=(node_type&) { return (*this); }
13838 
13839  T0 t0_;
13840  T1 t1_;
13841  T2 t2_;
13842  const bfunc_t f0_;
13843  const bfunc_t f1_;
13844  };
13845 
13846  template <typename T, typename T0_, typename T1_, typename T2_, typename T3_, typename ProcessMode>
13848  {
13849  public:
13850 
13852  typedef typename functor_t::bfunc_t bfunc_t;
13853  typedef T value_type;
13854  typedef T0_ T0;
13855  typedef T1_ T1;
13856  typedef T2_ T2;
13857  typedef T3_ T3;
13859  typedef ProcessMode process_mode_t;
13860 
13861  T0oT1oT2oT3(T0 p0, T1 p1, T2 p2, T3 p3, bfunc_t p4, bfunc_t p5, bfunc_t p6)
13862  : t0_(p0),
13863  t1_(p1),
13864  t2_(p2),
13865  t3_(p3),
13866  f0_(p4),
13867  f1_(p5),
13868  f2_(p6)
13869  {}
13870 
13871  inline T value() const
13872  {
13873  return ProcessMode::process(t0_, t1_, t2_, t3_, f0_, f1_, f2_);
13874  }
13875 
13876  inline T0 t0() const
13877  {
13878  return t0_;
13879  }
13880 
13881  inline T1 t1() const
13882  {
13883  return t1_;
13884  }
13885 
13886  inline T2 t2() const
13887  {
13888  return t2_;
13889  }
13890 
13891  inline T3 t3() const
13892  {
13893  return t3_;
13894  }
13895 
13896  inline bfunc_t f0() const
13897  {
13898  return f0_;
13899  }
13900 
13901  inline bfunc_t f1() const
13902  {
13903  return f1_;
13904  }
13905 
13906  inline bfunc_t f2() const
13907  {
13908  return f2_;
13909  }
13910 
13911  inline std::string type_id() const
13912  {
13913  return id();
13914  }
13915 
13916  static inline std::string id()
13917  {
13918  return process_mode_t::template id<T0,T1,T2,T3>();
13919  }
13920 
13921  template <typename Allocator>
13922  static inline expression_node<T>* allocate(Allocator& allocator,
13923  T0 p0, T1 p1, T2 p2, T3 p3,
13924  bfunc_t p4, bfunc_t p5, bfunc_t p6)
13925  {
13926  return allocator
13927  .template allocate_type<node_type,T0,T1,T2,T3,bfunc_t,bfunc_t>
13928  (p0, p1, p2, p3, p4, p5, p6);
13929  }
13930 
13931  private:
13932 
13934  node_type& operator=(node_type&) { return (*this); }
13935 
13936  T0 t0_;
13937  T1 t1_;
13938  T2 t2_;
13939  T3 t3_;
13940  const bfunc_t f0_;
13941  const bfunc_t f1_;
13942  const bfunc_t f2_;
13943  };
13944 
13945  template <typename T, typename T0, typename T1, typename T2>
13947  {
13948  public:
13949 
13951  typedef typename functor_t::tfunc_t tfunc_t;
13952  typedef T value_type;
13954 
13955  T0oT1oT2_sf3(T0 p0, T1 p1, T2 p2, const tfunc_t p3)
13956  : t0_(p0),
13957  t1_(p1),
13958  t2_(p2),
13959  f_ (p3)
13960  {}
13961 
13962  inline typename expression_node<T>::node_type type() const
13963  {
13965  return result;
13966  }
13967 
13968  inline operator_type operation() const
13969  {
13970  return e_default;
13971  }
13972 
13973  inline T value() const
13974  {
13975  return f_(t0_, t1_, t2_);
13976  }
13977 
13978  inline T0 t0() const
13979  {
13980  return t0_;
13981  }
13982 
13983  inline T1 t1() const
13984  {
13985  return t1_;
13986  }
13987 
13988  inline T2 t2() const
13989  {
13990  return t2_;
13991  }
13992 
13993  tfunc_t f() const
13994  {
13995  return f_;
13996  }
13997 
13998  std::string type_id() const
13999  {
14000  return id();
14001  }
14002 
14003  static inline std::string id()
14004  {
14005  return "sf3";
14006  }
14007 
14008  template <typename Allocator>
14009  static inline expression_node<T>* allocate(Allocator& allocator, T0 p0, T1 p1, T2 p2, tfunc_t p3)
14010  {
14011  return allocator
14012  .template allocate_type<node_type,T0,T1,T2,tfunc_t>
14013  (p0, p1, p2, p3);
14014  }
14015 
14016  private:
14017 
14019  node_type& operator=(node_type&) { return (*this); }
14020 
14021  T0 t0_;
14022  T1 t1_;
14023  T2 t2_;
14024  const tfunc_t f_;
14025  };
14026 
14027  template <typename T, typename T0, typename T1, typename T2>
14029  {
14030  public:
14031 
14033  {}
14034 
14035  virtual T0 t0() const = 0;
14036 
14037  virtual T1 t1() const = 0;
14038 
14039  virtual T2 t2() const = 0;
14040  };
14041 
14042  template <typename T, typename T0, typename T1, typename T2, typename SF3Operation>
14043  class T0oT1oT2_sf3ext : public sf3ext_type_node<T,T0,T1,T2>
14044  {
14045  public:
14046 
14048  typedef typename functor_t::tfunc_t tfunc_t;
14049  typedef T value_type;
14051 
14052  T0oT1oT2_sf3ext(T0 p0, T1 p1, T2 p2)
14053  : t0_(p0),
14054  t1_(p1),
14055  t2_(p2)
14056  {}
14057 
14058  inline typename expression_node<T>::node_type type() const
14059  {
14061  return result;
14062  }
14063 
14064  inline operator_type operation() const
14065  {
14066  return e_default;
14067  }
14068 
14069  inline T value() const
14070  {
14071  return SF3Operation::process(t0_, t1_, t2_);
14072  }
14073 
14074  T0 t0() const
14075  {
14076  return t0_;
14077  }
14078 
14079  T1 t1() const
14080  {
14081  return t1_;
14082  }
14083 
14084  T2 t2() const
14085  {
14086  return t2_;
14087  }
14088 
14089  std::string type_id() const
14090  {
14091  return id();
14092  }
14093 
14094  static inline std::string id()
14095  {
14096  return SF3Operation::id();
14097  }
14098 
14099  template <typename Allocator>
14100  static inline expression_node<T>* allocate(Allocator& allocator, T0 p0, T1 p1, T2 p2)
14101  {
14102  return allocator
14103  .template allocate_type<node_type,T0,T1,T2>
14104  (p0, p1, p2);
14105  }
14106 
14107  private:
14108 
14110  node_type& operator=(node_type&) { return (*this); }
14111 
14112  T0 t0_;
14113  T1 t1_;
14114  T2 t2_;
14115  };
14116 
14117  template <typename T>
14118  inline bool is_sf3ext_node(const expression_node<T>* n)
14119  {
14120  switch (n->type())
14121  {
14122  case expression_node<T>::e_vovov : return true;
14123  case expression_node<T>::e_vovoc : return true;
14124  case expression_node<T>::e_vocov : return true;
14125  case expression_node<T>::e_covov : return true;
14126  case expression_node<T>::e_covoc : return true;
14127  default : return false;
14128  }
14129  }
14130 
14131  template <typename T, typename T0, typename T1, typename T2, typename T3>
14133  {
14134  public:
14135 
14137  typedef typename functor_t::qfunc_t qfunc_t;
14138  typedef T value_type;
14140 
14141  T0oT1oT2oT3_sf4(T0 p0, T1 p1, T2 p2, T3 p3, const qfunc_t p4)
14142  : t0_(p0),
14143  t1_(p1),
14144  t2_(p2),
14145  t3_(p3),
14146  f_ (p4)
14147  {}
14148 
14149  inline typename expression_node<T>::node_type type() const
14150  {
14152  return result;
14153  }
14154 
14155  inline operator_type operation() const
14156  {
14157  return e_default;
14158  }
14159 
14160  inline T value() const
14161  {
14162  return f_(t0_, t1_, t2_, t3_);
14163  }
14164 
14165  inline T0 t0() const
14166  {
14167  return t0_;
14168  }
14169 
14170  inline T1 t1() const
14171  {
14172  return t1_;
14173  }
14174 
14175  inline T2 t2() const
14176  {
14177  return t2_;
14178  }
14179 
14180  inline T3 t3() const
14181  {
14182  return t3_;
14183  }
14184 
14185  qfunc_t f() const
14186  {
14187  return f_;
14188  }
14189 
14190  std::string type_id() const
14191  {
14192  return id();
14193  }
14194 
14195  static inline std::string id()
14196  {
14197  return "sf4";
14198  }
14199 
14200  template <typename Allocator>
14201  static inline expression_node<T>* allocate(Allocator& allocator, T0 p0, T1 p1, T2 p2, T3 p3, qfunc_t p4)
14202  {
14203  return allocator
14204  .template allocate_type<node_type,T0,T1,T2,T3,qfunc_t>
14205  (p0, p1, p2, p3, p4);
14206  }
14207 
14208  private:
14209 
14211  node_type& operator=(node_type&) { return (*this); }
14212 
14213  T0 t0_;
14214  T1 t1_;
14215  T2 t2_;
14216  T3 t3_;
14217  const qfunc_t f_;
14218  };
14219 
14220  template <typename T, typename T0, typename T1, typename T2, typename T3, typename SF4Operation>
14222  {
14223  public:
14224 
14226  typedef typename functor_t::tfunc_t tfunc_t;
14227  typedef T value_type;
14229 
14230  T0oT1oT2oT3_sf4ext(T0 p0, T1 p1, T2 p2, T3 p3)
14231  : t0_(p0),
14232  t1_(p1),
14233  t2_(p2),
14234  t3_(p3)
14235  {}
14236 
14237  inline typename expression_node<T>::node_type type() const
14238  {
14240  return result;
14241  }
14242 
14243  inline operator_type operation() const
14244  {
14245  return e_default;
14246  }
14247 
14248  inline T value() const
14249  {
14250  return SF4Operation::process(t0_, t1_, t2_, t3_);
14251  }
14252 
14253  inline T0 t0() const
14254  {
14255  return t0_;
14256  }
14257 
14258  inline T1 t1() const
14259  {
14260  return t1_;
14261  }
14262 
14263  inline T2 t2() const
14264  {
14265  return t2_;
14266  }
14267 
14268  inline T3 t3() const
14269  {
14270  return t2_;
14271  }
14272 
14273  std::string type_id() const
14274  {
14275  return id();
14276  }
14277 
14278  static inline std::string id()
14279  {
14280  return SF4Operation::id();
14281  }
14282 
14283  template <typename Allocator>
14284  static inline expression_node<T>* allocate(Allocator& allocator, T0 p0, T1 p1, T2 p2, T3 p3)
14285  {
14286  return allocator
14287  .template allocate_type<node_type,T0,T1,T2,T3>
14288  (p0, p1, p2, p3);
14289  }
14290 
14291  private:
14292 
14294  node_type& operator=(node_type&) { return (*this); }
14295 
14296  T0 t0_;
14297  T1 t1_;
14298  T2 t2_;
14299  T3 t3_;
14300  };
14301 
14302  template <typename T>
14303  inline bool is_sf4ext_node(const expression_node<T>* n)
14304  {
14305  switch (n->type())
14306  {
14307  case expression_node<T>::e_vovovov : return true;
14308  case expression_node<T>::e_vovovoc : return true;
14309  case expression_node<T>::e_vovocov : return true;
14310  case expression_node<T>::e_vocovov : return true;
14311  case expression_node<T>::e_covovov : return true;
14312  case expression_node<T>::e_covocov : return true;
14313  case expression_node<T>::e_vocovoc : return true;
14314  case expression_node<T>::e_covovoc : return true;
14315  case expression_node<T>::e_vococov : return true;
14316  default : return false;
14317  }
14318  }
14319 
14320  template <typename T, typename T0, typename T1>
14322  {
14324  };
14325 
14326  template <typename T, typename T0, typename T1, typename T2>
14328  {
14333  };
14334 
14335  template <typename T, typename T0, typename T1, typename T2, typename T3>
14337  {
14344  };
14345 
14346  template <typename T, typename Operation>
14347  class vov_node : public vov_base_node<T>
14348  {
14349  public:
14350 
14352  typedef Operation operation_t;
14353 
14354  // variable op variable node
14355  explicit vov_node(const T& var0, const T& var1)
14356  : v0_(var0),
14357  v1_(var1)
14358  {}
14359 
14360  inline T value() const
14361  {
14362  return Operation::process(v0_,v1_);
14363  }
14364 
14365  inline typename expression_node<T>::node_type type() const
14366  {
14367  return Operation::type();
14368  }
14369 
14370  inline operator_type operation() const
14371  {
14372  return Operation::operation();
14373  }
14374 
14375  inline const T& v0() const
14376  {
14377  return v0_;
14378  }
14379 
14380  inline const T& v1() const
14381  {
14382  return v1_;
14383  }
14384 
14385  protected:
14386 
14387  const T& v0_;
14388  const T& v1_;
14389 
14390  private:
14391 
14394  };
14395 
14396  template <typename T, typename Operation>
14397  class cov_node : public cov_base_node<T>
14398  {
14399  public:
14400 
14402  typedef Operation operation_t;
14403 
14404  // constant op variable node
14405  explicit cov_node(const T& const_var, const T& var)
14406  : c_(const_var),
14407  v_(var)
14408  {}
14409 
14410  inline T value() const
14411  {
14412  return Operation::process(c_,v_);
14413  }
14414 
14415  inline typename expression_node<T>::node_type type() const
14416  {
14417  return Operation::type();
14418  }
14419 
14420  inline operator_type operation() const
14421  {
14422  return Operation::operation();
14423  }
14424 
14425  inline const T c() const
14426  {
14427  return c_;
14428  }
14429 
14430  inline const T& v() const
14431  {
14432  return v_;
14433  }
14434 
14435  protected:
14436 
14437  const T c_;
14438  const T& v_;
14439 
14440  private:
14441 
14444  };
14445 
14446  template <typename T, typename Operation>
14447  class voc_node : public voc_base_node<T>
14448  {
14449  public:
14450 
14452  typedef Operation operation_t;
14453 
14454  // variable op constant node
14455  explicit voc_node(const T& var, const T& const_var)
14456  : v_(var),
14457  c_(const_var)
14458  {}
14459 
14460  inline T value() const
14461  {
14462  return Operation::process(v_,c_);
14463  }
14464 
14465  inline operator_type operation() const
14466  {
14467  return Operation::operation();
14468  }
14469 
14470  inline const T c() const
14471  {
14472  return c_;
14473  }
14474 
14475  inline const T& v() const
14476  {
14477  return v_;
14478  }
14479 
14480  protected:
14481 
14482  const T& v_;
14483  const T c_;
14484 
14485  private:
14486 
14489  };
14490 
14491  template <typename T, typename Operation>
14492  class vob_node : public vob_base_node<T>
14493  {
14494  public:
14495 
14497  typedef std::pair<expression_ptr,bool> branch_t;
14498  typedef Operation operation_t;
14499 
14500  // variable op constant node
14501  explicit vob_node(const T& var, const expression_ptr brnch)
14502  : v_(var)
14503  {
14504  init_branches<1>(branch_,brnch);
14505  }
14506 
14508  {
14509  cleanup_branches::execute<T,1>(branch_);
14510  }
14511 
14512  inline T value() const
14513  {
14514  return Operation::process(v_,branch_[0].first->value());
14515  }
14516 
14517  inline operator_type operation() const
14518  {
14519  return Operation::operation();
14520  }
14521 
14522  inline const T& v() const
14523  {
14524  return v_;
14525  }
14526 
14527  inline expression_node<T>* branch(const std::size_t&) const
14528  {
14529  return branch_[0].first;
14530  }
14531 
14532  private:
14533 
14536 
14537  const T& v_;
14539  };
14540 
14541  template <typename T, typename Operation>
14542  class bov_node : public bov_base_node<T>
14543  {
14544  public:
14545 
14547  typedef std::pair<expression_ptr,bool> branch_t;
14548  typedef Operation operation_t;
14549 
14550  // variable op constant node
14551  explicit bov_node(const expression_ptr brnch, const T& var)
14552  : v_(var)
14553  {
14554  init_branches<1>(branch_,brnch);
14555  }
14556 
14558  {
14559  cleanup_branches::execute<T,1>(branch_);
14560  }
14561 
14562  inline T value() const
14563  {
14564  return Operation::process(branch_[0].first->value(),v_);
14565  }
14566 
14567  inline operator_type operation() const
14568  {
14569  return Operation::operation();
14570  }
14571 
14572  inline const T& v() const
14573  {
14574  return v_;
14575  }
14576 
14577  inline expression_node<T>* branch(const std::size_t&) const
14578  {
14579  return branch_[0].first;
14580  }
14581 
14582  private:
14583 
14586 
14587  const T& v_;
14589  };
14590 
14591  template <typename T, typename Operation>
14592  class cob_node : public cob_base_node<T>
14593  {
14594  public:
14595 
14597  typedef std::pair<expression_ptr,bool> branch_t;
14598  typedef Operation operation_t;
14599 
14600  // variable op constant node
14601  explicit cob_node(const T const_var, const expression_ptr brnch)
14602  : c_(const_var)
14603  {
14604  init_branches<1>(branch_,brnch);
14605  }
14606 
14608  {
14609  cleanup_branches::execute<T,1>(branch_);
14610  }
14611 
14612  inline T value() const
14613  {
14614  return Operation::process(c_,branch_[0].first->value());
14615  }
14616 
14617  inline operator_type operation() const
14618  {
14619  return Operation::operation();
14620  }
14621 
14622  inline const T c() const
14623  {
14624  return c_;
14625  }
14626 
14627  inline void set_c(const T new_c)
14628  {
14629  (*const_cast<T*>(&c_)) = new_c;
14630  }
14631 
14632  inline expression_node<T>* branch(const std::size_t&) const
14633  {
14634  return branch_[0].first;
14635  }
14636 
14637  inline expression_node<T>* move_branch(const std::size_t&)
14638  {
14639  branch_[0].second = false;
14640  return branch_[0].first;
14641  }
14642 
14643  private:
14644 
14647 
14648  const T c_;
14650  };
14651 
14652  template <typename T, typename Operation>
14653  class boc_node : public boc_base_node<T>
14654  {
14655  public:
14656 
14658  typedef std::pair<expression_ptr,bool> branch_t;
14659  typedef Operation operation_t;
14660 
14661  // variable op constant node
14662  explicit boc_node(const expression_ptr brnch, const T const_var)
14663  : c_(const_var)
14664  {
14665  init_branches<1>(branch_,brnch);
14666  }
14667 
14669  {
14670  cleanup_branches::execute<T,1>(branch_);
14671  }
14672 
14673  inline T value() const
14674  {
14675  return Operation::process(branch_[0].first->value(),c_);
14676  }
14677 
14678  inline operator_type operation() const
14679  {
14680  return Operation::operation();
14681  }
14682 
14683  inline const T c() const
14684  {
14685  return c_;
14686  }
14687 
14688  inline void set_c(const T new_c)
14689  {
14690  (*const_cast<T*>(&c_)) = new_c;
14691  }
14692 
14693  inline expression_node<T>* branch(const std::size_t&) const
14694  {
14695  return branch_[0].first;
14696  }
14697 
14698  inline expression_node<T>* move_branch(const std::size_t&)
14699  {
14700  branch_[0].second = false;
14701  return branch_[0].first;
14702  }
14703 
14704  private:
14705 
14708 
14709  const T c_;
14711  };
14712 
14713  #ifndef exprtk_disable_string_capabilities
14714  template <typename T, typename SType0, typename SType1, typename Operation>
14715  class sos_node : public sos_base_node<T>
14716  {
14717  public:
14718 
14720  typedef Operation operation_t;
14721 
14722  // string op string node
14723  explicit sos_node(SType0 p0, SType1 p1)
14724  : s0_(p0),
14725  s1_(p1)
14726  {}
14727 
14728  inline T value() const
14729  {
14730  return Operation::process(s0_,s1_);
14731  }
14732 
14733  inline typename expression_node<T>::node_type type() const
14734  {
14735  return Operation::type();
14736  }
14737 
14738  inline operator_type operation() const
14739  {
14740  return Operation::operation();
14741  }
14742 
14743  inline std::string& s0()
14744  {
14745  return s0_;
14746  }
14747 
14748  inline std::string& s1()
14749  {
14750  return s1_;
14751  }
14752 
14753  protected:
14754 
14755  SType0 s0_;
14756  SType1 s1_;
14757 
14758  private:
14759 
14762  };
14763 
14764  template <typename T, typename SType0, typename SType1, typename RangePack, typename Operation>
14765  class str_xrox_node : public sos_base_node<T>
14766  {
14767  public:
14768 
14770  typedef Operation operation_t;
14771 
14772  // string-range op string node
14773  explicit str_xrox_node(SType0 p0, SType1 p1, RangePack rp0)
14774  : s0_ (p0 ),
14775  s1_ (p1 ),
14776  rp0_(rp0)
14777  {}
14778 
14780  {
14781  rp0_.free();
14782  }
14783 
14784  inline T value() const
14785  {
14786  std::size_t r0 = 0;
14787  std::size_t r1 = 0;
14788 
14789  if (rp0_(r0, r1, s0_.size()))
14790  return Operation::process(s0_.substr(r0, (r1 - r0) + 1), s1_);
14791  else
14792  return T(0);
14793  }
14794 
14795  inline typename expression_node<T>::node_type type() const
14796  {
14797  return Operation::type();
14798  }
14799 
14800  inline operator_type operation() const
14801  {
14802  return Operation::operation();
14803  }
14804 
14805  inline std::string& s0()
14806  {
14807  return s0_;
14808  }
14809 
14810  inline std::string& s1()
14811  {
14812  return s1_;
14813  }
14814 
14815  protected:
14816 
14817  SType0 s0_;
14818  SType1 s1_;
14819  RangePack rp0_;
14820 
14821  private:
14822 
14825  };
14826 
14827  template <typename T, typename SType0, typename SType1, typename RangePack, typename Operation>
14828  class str_xoxr_node : public sos_base_node<T>
14829  {
14830  public:
14831 
14833  typedef Operation operation_t;
14834 
14835  // string op string range node
14836  explicit str_xoxr_node(SType0 p0, SType1 p1, RangePack rp1)
14837  : s0_ (p0 ),
14838  s1_ (p1 ),
14839  rp1_(rp1)
14840  {}
14841 
14843  {
14844  rp1_.free();
14845  }
14846 
14847  inline T value() const
14848  {
14849  std::size_t r0 = 0;
14850  std::size_t r1 = 0;
14851 
14852  if (rp1_(r0, r1, s1_.size()))
14853  return Operation::process(s0_, s1_.substr(r0, (r1 - r0) + 1));
14854  else
14855  return T(0);
14856  }
14857 
14858  inline typename expression_node<T>::node_type type() const
14859  {
14860  return Operation::type();
14861  }
14862 
14863  inline operator_type operation() const
14864  {
14865  return Operation::operation();
14866  }
14867 
14868  inline std::string& s0()
14869  {
14870  return s0_;
14871  }
14872 
14873  inline std::string& s1()
14874  {
14875  return s1_;
14876  }
14877 
14878  protected:
14879 
14880  SType0 s0_;
14881  SType1 s1_;
14882  RangePack rp1_;
14883 
14884  private:
14885 
14888  };
14889 
14890  template <typename T, typename SType0, typename SType1, typename RangePack, typename Operation>
14891  class str_xroxr_node : public sos_base_node<T>
14892  {
14893  public:
14894 
14896  typedef Operation operation_t;
14897 
14898  // string-range op string-range node
14899  explicit str_xroxr_node(SType0 p0, SType1 p1, RangePack rp0, RangePack rp1)
14900  : s0_ (p0 ),
14901  s1_ (p1 ),
14902  rp0_(rp0),
14903  rp1_(rp1)
14904  {}
14905 
14907  {
14908  rp0_.free();
14909  rp1_.free();
14910  }
14911 
14912  inline T value() const
14913  {
14914  std::size_t r0_0 = 0;
14915  std::size_t r0_1 = 0;
14916  std::size_t r1_0 = 0;
14917  std::size_t r1_1 = 0;
14918 
14919  if (
14920  rp0_(r0_0, r1_0, s0_.size()) &&
14921  rp1_(r0_1, r1_1, s1_.size())
14922  )
14923  {
14924  return Operation::process(
14925  s0_.substr(r0_0, (r1_0 - r0_0) + 1),
14926  s1_.substr(r0_1, (r1_1 - r0_1) + 1)
14927  );
14928  }
14929  else
14930  return T(0);
14931  }
14932 
14933  inline typename expression_node<T>::node_type type() const
14934  {
14935  return Operation::type();
14936  }
14937 
14938  inline operator_type operation() const
14939  {
14940  return Operation::operation();
14941  }
14942 
14943  inline std::string& s0()
14944  {
14945  return s0_;
14946  }
14947 
14948  inline std::string& s1()
14949  {
14950  return s1_;
14951  }
14952 
14953  protected:
14954 
14955  SType0 s0_;
14956  SType1 s1_;
14957  RangePack rp0_;
14958  RangePack rp1_;
14959 
14960  private:
14961 
14964  };
14965 
14966  template <typename T, typename Operation>
14967  class str_sogens_node : public binary_node<T>
14968  {
14969  public:
14970 
14974  typedef range_t* range_ptr;
14977 
14979  expression_ptr branch0,
14980  expression_ptr branch1)
14981  : binary_node<T>(opr, branch0, branch1),
14982  str0_base_ptr_ (0),
14983  str1_base_ptr_ (0),
14984  str0_range_ptr_(0),
14985  str1_range_ptr_(0)
14986  {
14988  {
14989  str0_base_ptr_ = dynamic_cast<str_base_ptr>(binary_node<T>::branch_[0].first);
14990 
14991  if (0 == str0_base_ptr_)
14992  return;
14993 
14994  irange_ptr range = dynamic_cast<irange_ptr>(binary_node<T>::branch_[0].first);
14995 
14996  if (0 == range)
14997  return;
14998 
14999  str0_range_ptr_ = &(range->range_ref());
15000  }
15001 
15003  {
15004  str1_base_ptr_ = dynamic_cast<str_base_ptr>(binary_node<T>::branch_[1].first);
15005 
15006  if (0 == str1_base_ptr_)
15007  return;
15008 
15009  irange_ptr range = dynamic_cast<irange_ptr>(binary_node<T>::branch_[1].first);
15010 
15011  if (0 == range)
15012  return;
15013 
15014  str1_range_ptr_ = &(range->range_ref());
15015  }
15016  }
15017 
15018  inline T value() const
15019  {
15020  if (
15021  str0_base_ptr_ &&
15022  str1_base_ptr_ &&
15023  str0_range_ptr_ &&
15025  )
15026  {
15027  binary_node<T>::branch_[0].first->value();
15028  binary_node<T>::branch_[1].first->value();
15029 
15030  std::size_t str0_r0 = 0;
15031  std::size_t str0_r1 = 0;
15032 
15033  std::size_t str1_r0 = 0;
15034  std::size_t str1_r1 = 0;
15035 
15036  range_t& range0 = (*str0_range_ptr_);
15037  range_t& range1 = (*str1_range_ptr_);
15038 
15039  if (
15040  range0(str0_r0, str0_r1, str0_base_ptr_->size()) &&
15041  range1(str1_r0, str1_r1, str1_base_ptr_->size())
15042  )
15043  {
15044  return Operation::process(
15045  str0_base_ptr_->str().substr(str0_r0,(str0_r1 - str0_r0) + 1),
15046  str1_base_ptr_->str().substr(str1_r0,(str1_r1 - str1_r0) + 1)
15047  );
15048  }
15049  }
15050 
15051  return std::numeric_limits<T>::quiet_NaN();
15052  }
15053 
15054  inline typename expression_node<T>::node_type type() const
15055  {
15056  return Operation::type();
15057  }
15058 
15059  inline operator_type operation() const
15060  {
15061  return Operation::operation();
15062  }
15063 
15064  private:
15065 
15068 
15073  };
15074 
15075  template <typename T, typename SType0, typename SType1, typename SType2, typename Operation>
15076  class sosos_node : public sosos_base_node<T>
15077  {
15078  public:
15079 
15081  typedef Operation operation_t;
15082 
15083  // variable op variable node
15084  explicit sosos_node(SType0 p0, SType1 p1, SType2 p2)
15085  : s0_(p0),
15086  s1_(p1),
15087  s2_(p2)
15088  {}
15089 
15090  inline T value() const
15091  {
15092  return Operation::process(s0_,s1_,s2_);
15093  }
15094 
15095  inline typename expression_node<T>::node_type type() const
15096  {
15097  return Operation::type();
15098  }
15099 
15100  inline operator_type operation() const
15101  {
15102  return Operation::operation();
15103  }
15104 
15105  inline std::string& s0()
15106  {
15107  return s0_;
15108  }
15109 
15110  inline std::string& s1()
15111  {
15112  return s1_;
15113  }
15114 
15115  inline std::string& s2()
15116  {
15117  return s2_;
15118  }
15119 
15120  protected:
15121 
15122  SType0 s0_;
15123  SType1 s1_;
15124  SType2 s2_;
15125 
15126  private:
15127 
15130  };
15131  #endif
15132 
15133  template <typename T, typename PowOp>
15134  class ipow_node : public expression_node<T>
15135  {
15136  public:
15137 
15139  typedef PowOp operation_t;
15140 
15141  explicit ipow_node(const T& v)
15142  : v_(v)
15143  {}
15144 
15145  inline T value() const
15146  {
15147  return PowOp::result(v_);
15148  }
15149 
15150  inline typename expression_node<T>::node_type type() const
15151  {
15153  }
15154 
15155  private:
15156 
15157  ipow_node(const ipow_node<T,PowOp>&);
15159 
15160  const T& v_;
15161  };
15162 
15163  template <typename T, typename PowOp>
15164  class bipow_node : public expression_node<T>
15165  {
15166  public:
15167 
15169  typedef std::pair<expression_ptr, bool> branch_t;
15170  typedef PowOp operation_t;
15171 
15172  explicit bipow_node(expression_ptr brnch)
15173  {
15174  init_branches<1>(branch_, brnch);
15175  }
15176 
15178  {
15179  cleanup_branches::execute<T,1>(branch_);
15180  }
15181 
15182  inline T value() const
15183  {
15184  return PowOp::result(branch_[0].first->value());
15185  }
15186 
15187  inline typename expression_node<T>::node_type type() const
15188  {
15190  }
15191 
15192  private:
15193 
15196 
15198  };
15199 
15200  template <typename T, typename PowOp>
15201  class ipowinv_node : public expression_node<T>
15202  {
15203  public:
15204 
15206  typedef PowOp operation_t;
15207 
15208  explicit ipowinv_node(const T& v)
15209  : v_(v)
15210  {}
15211 
15212  inline T value() const
15213  {
15214  return (T(1) / PowOp::result(v_));
15215  }
15216 
15217  inline typename expression_node<T>::node_type type() const
15218  {
15220  }
15221 
15222  private:
15223 
15226 
15227  const T& v_;
15228  };
15229 
15230  template <typename T, typename PowOp>
15232  {
15233  public:
15234 
15236  typedef std::pair<expression_ptr, bool> branch_t;
15237  typedef PowOp operation_t;
15238 
15240  {
15241  init_branches<1>(branch_, brnch);
15242  }
15243 
15245  {
15246  cleanup_branches::execute<T,1>(branch_);
15247  }
15248 
15249  inline T value() const
15250  {
15251  return (T(1) / PowOp::result(branch_[0].first->value()));
15252  }
15253 
15254  inline typename expression_node<T>::node_type type() const
15255  {
15257  }
15258 
15259  private:
15260 
15263 
15265  };
15266 
15267  template <typename T>
15268  inline bool is_vov_node(const expression_node<T>* node)
15269  {
15270  return (0 != dynamic_cast<const vov_base_node<T>*>(node));
15271  }
15272 
15273  template <typename T>
15274  inline bool is_cov_node(const expression_node<T>* node)
15275  {
15276  return (0 != dynamic_cast<const cov_base_node<T>*>(node));
15277  }
15278 
15279  template <typename T>
15280  inline bool is_voc_node(const expression_node<T>* node)
15281  {
15282  return (0 != dynamic_cast<const voc_base_node<T>*>(node));
15283  }
15284 
15285  template <typename T>
15286  inline bool is_cob_node(const expression_node<T>* node)
15287  {
15288  return (0 != dynamic_cast<const cob_base_node<T>*>(node));
15289  }
15290 
15291  template <typename T>
15292  inline bool is_boc_node(const expression_node<T>* node)
15293  {
15294  return (0 != dynamic_cast<const boc_base_node<T>*>(node));
15295  }
15296 
15297  template <typename T>
15298  inline bool is_t0ot1ot2_node(const expression_node<T>* node)
15299  {
15300  return (0 != dynamic_cast<const T0oT1oT2_base_node<T>*>(node));
15301  }
15302 
15303  template <typename T>
15304  inline bool is_t0ot1ot2ot3_node(const expression_node<T>* node)
15305  {
15306  return (0 != dynamic_cast<const T0oT1oT2oT3_base_node<T>*>(node));
15307  }
15308 
15309  template <typename T>
15310  inline bool is_uv_node(const expression_node<T>* node)
15311  {
15312  return (0 != dynamic_cast<const uv_base_node<T>*>(node));
15313  }
15314 
15315  template <typename T>
15316  inline bool is_string_node(const expression_node<T>* node)
15317  {
15318  return node && (expression_node<T>::e_stringvar == node->type());
15319  }
15320 
15321  template <typename T>
15322  inline bool is_string_range_node(const expression_node<T>* node)
15323  {
15324  return node && (expression_node<T>::e_stringvarrng == node->type());
15325  }
15326 
15327  template <typename T>
15328  inline bool is_const_string_node(const expression_node<T>* node)
15329  {
15330  return node && (expression_node<T>::e_stringconst == node->type());
15331  }
15332 
15333  template <typename T>
15335  {
15336  return node && (expression_node<T>::e_cstringvarrng == node->type());
15337  }
15338 
15339  template <typename T>
15341  {
15342  return node && (expression_node<T>::e_strass == node->type());
15343  }
15344 
15345  template <typename T>
15347  {
15348  return node && (expression_node<T>::e_strconcat == node->type());
15349  }
15350 
15351  template <typename T>
15353  {
15354  return node && (expression_node<T>::e_strfunction == node->type());
15355  }
15356 
15357  template <typename T>
15359  {
15360  return node && (expression_node<T>::e_strcondition == node->type());
15361  }
15362 
15363  template <typename T>
15365  {
15366  return node && (expression_node<T>::e_strccondition == node->type());
15367  }
15368 
15369  template <typename T>
15371  {
15372  return node && (expression_node<T>::e_stringvararg == node->type());
15373  }
15374 
15375  template <typename T>
15377  {
15378  return node && (expression_node<T>::e_strgenrange == node->type());
15379  }
15380 
15381  template <typename T>
15383  {
15384  if (node)
15385  {
15386  switch (node->type())
15387  {
15398  case expression_node<T>::e_stringvararg : return true;
15399  default : return false;
15400  }
15401  }
15402 
15403  return false;
15404  }
15405 
15406  class node_allocator
15407  {
15408  public:
15409 
15410  template <typename ResultNode, typename OpType, typename ExprNode>
15411  inline expression_node<typename ResultNode::value_type>* allocate(OpType& operation, ExprNode (&branch)[1])
15412  {
15413  return allocate<ResultNode>(operation,branch[0]);
15414  }
15415 
15416  template <typename ResultNode, typename OpType, typename ExprNode>
15417  inline expression_node<typename ResultNode::value_type>* allocate(OpType& operation, ExprNode (&branch)[2])
15418  {
15419  return allocate<ResultNode>(operation,branch[0],branch[1]);
15420  }
15421 
15422  template <typename ResultNode, typename OpType, typename ExprNode>
15423  inline expression_node<typename ResultNode::value_type>* allocate(OpType& operation, ExprNode (&branch)[3])
15424  {
15425  return allocate<ResultNode>(operation,branch[0],branch[1],branch[2]);
15426  }
15427 
15428  template <typename ResultNode, typename OpType, typename ExprNode>
15429  inline expression_node<typename ResultNode::value_type>* allocate(OpType& operation, ExprNode (&branch)[4])
15430  {
15431  return allocate<ResultNode>(operation,branch[0],branch[1],branch[2],branch[3]);
15432  }
15433 
15434  template <typename ResultNode, typename OpType, typename ExprNode>
15435  inline expression_node<typename ResultNode::value_type>* allocate(OpType& operation, ExprNode (&branch)[5])
15436  {
15437  return allocate<ResultNode>(operation,branch[0],branch[1],branch[2],branch[3],branch[4]);
15438  }
15439 
15440  template <typename ResultNode, typename OpType, typename ExprNode>
15441  inline expression_node<typename ResultNode::value_type>* allocate(OpType& operation, ExprNode (&branch)[6])
15442  {
15443  return allocate<ResultNode>(operation,branch[0],branch[1],branch[2],branch[3],branch[4],branch[5]);
15444  }
15445 
15446  template <typename node_type>
15448  {
15449  return (new node_type());
15450  }
15451 
15452  template <typename node_type,
15453  typename Type,
15454  typename Allocator,
15455  template <typename,typename> class Sequence>
15456  inline expression_node<typename node_type::value_type>* allocate(const Sequence<Type,Allocator>& seq) const
15457  {
15458  return (new node_type(seq));
15459  }
15460 
15461  template <typename node_type, typename T1>
15463  {
15464  return (new node_type(t1));
15465  }
15466 
15467  template <typename node_type, typename T1>
15469  {
15470  return (new node_type(t1));
15471  }
15472 
15473  template <typename node_type,
15474  typename T1, typename T2>
15475  inline expression_node<typename node_type::value_type>* allocate(const T1& t1, const T2& t2) const
15476  {
15477  return (new node_type(t1, t2));
15478  }
15479 
15480  template <typename node_type,
15481  typename T1, typename T2>
15483  {
15484  return (new node_type(t1, t2));
15485  }
15486 
15487  template <typename node_type,
15488  typename T1, typename T2>
15490  {
15491  return (new node_type(t1, t2));
15492  }
15493 
15494  template <typename node_type,
15495  typename T1, typename T2>
15497  {
15498  return (new node_type(t1, t2));
15499  }
15500 
15501  template <typename node_type,
15502  typename T1, typename T2>
15504  {
15505  return (new node_type(t1, t2));
15506  }
15507 
15508  template <typename node_type,
15509  typename T1, typename T2, typename T3>
15511  {
15512  return (new node_type(t1, t2, t3));
15513  }
15514 
15515  template <typename node_type,
15516  typename T1, typename T2, typename T3, typename T4>
15517  inline expression_node<typename node_type::value_type>* allocate_tttt(T1 t1, T2 t2, T3 t3, T4 t4) const
15518  {
15519  return (new node_type(t1, t2, t3, t4));
15520  }
15521 
15522  template <typename node_type,
15523  typename T1, typename T2, typename T3>
15525  {
15526  return (new node_type(t1, t2, t3));
15527  }
15528 
15529  template <typename node_type,
15530  typename T1, typename T2, typename T3, typename T4>
15531  inline expression_node<typename node_type::value_type>* allocate_rrrr(T1& t1, T2& t2, T3& t3, T4& t4) const
15532  {
15533  return (new node_type(t1, t2, t3, t4));
15534  }
15535 
15536  template <typename node_type,
15537  typename T1, typename T2, typename T3, typename T4, typename T5>
15538  inline expression_node<typename node_type::value_type>* allocate_rrrrr(T1& t1, T2& t2, T3& t3, T4& t4, T5& t5) const
15539  {
15540  return (new node_type(t1, t2, t3, t4, t5));
15541  }
15542 
15543  template <typename node_type,
15544  typename T1, typename T2, typename T3>
15545  inline expression_node<typename node_type::value_type>* allocate(const T1& t1, const T2& t2,
15546  const T3& t3) const
15547  {
15548  return (new node_type(t1, t2, t3));
15549  }
15550 
15551  template <typename node_type,
15552  typename T1, typename T2,
15553  typename T3, typename T4>
15554  inline expression_node<typename node_type::value_type>* allocate(const T1& t1, const T2& t2,
15555  const T3& t3, const T4& t4) const
15556  {
15557  return (new node_type(t1, t2, t3, t4));
15558  }
15559 
15560  template <typename node_type,
15561  typename T1, typename T2,
15562  typename T3, typename T4, typename T5>
15563  inline expression_node<typename node_type::value_type>* allocate(const T1& t1, const T2& t2,
15564  const T3& t3, const T4& t4,
15565  const T5& t5) const
15566  {
15567  return (new node_type(t1, t2, t3, t4, t5));
15568  }
15569 
15570  template <typename node_type,
15571  typename T1, typename T2,
15572  typename T3, typename T4, typename T5, typename T6>
15573  inline expression_node<typename node_type::value_type>* allocate(const T1& t1, const T2& t2,
15574  const T3& t3, const T4& t4,
15575  const T5& t5, const T6& t6) const
15576  {
15577  return (new node_type(t1, t2, t3, t4, t5, t6));
15578  }
15579 
15580  template <typename node_type,
15581  typename T1, typename T2,
15582  typename T3, typename T4,
15583  typename T5, typename T6, typename T7>
15584  inline expression_node<typename node_type::value_type>* allocate(const T1& t1, const T2& t2,
15585  const T3& t3, const T4& t4,
15586  const T5& t5, const T6& t6,
15587  const T7& t7) const
15588  {
15589  return (new node_type(t1, t2, t3, t4, t5, t6, t7));
15590  }
15591 
15592  template <typename node_type,
15593  typename T1, typename T2,
15594  typename T3, typename T4,
15595  typename T5, typename T6,
15596  typename T7, typename T8>
15597  inline expression_node<typename node_type::value_type>* allocate(const T1& t1, const T2& t2,
15598  const T3& t3, const T4& t4,
15599  const T5& t5, const T6& t6,
15600  const T7& t7, const T8& t8) const
15601  {
15602  return (new node_type(t1, t2, t3, t4, t5, t6, t7, t8));
15603  }
15604 
15605  template <typename node_type,
15606  typename T1, typename T2,
15607  typename T3, typename T4,
15608  typename T5, typename T6,
15609  typename T7, typename T8, typename T9>
15610  inline expression_node<typename node_type::value_type>* allocate(const T1& t1, const T2& t2,
15611  const T3& t3, const T4& t4,
15612  const T5& t5, const T6& t6,
15613  const T7& t7, const T8& t8,
15614  const T9& t9) const
15615  {
15616  return (new node_type(t1, t2, t3, t4, t5, t6, t7, t8, t9));
15617  }
15618 
15619  template <typename node_type,
15620  typename T1, typename T2,
15621  typename T3, typename T4,
15622  typename T5, typename T6,
15623  typename T7, typename T8,
15624  typename T9, typename T10>
15625  inline expression_node<typename node_type::value_type>* allocate(const T1& t1, const T2& t2,
15626  const T3& t3, const T4& t4,
15627  const T5& t5, const T6& t6,
15628  const T7& t7, const T8& t8,
15629  const T9& t9, const T10& t10) const
15630  {
15631  return (new node_type(t1, t2, t3, t4, t5, t6, t7, t8, t9, t10));
15632  }
15633 
15634  template <typename node_type,
15635  typename T1, typename T2, typename T3>
15637  {
15638  return (new node_type(t1, t2, t3));
15639  }
15640 
15641  template <typename node_type,
15642  typename T1, typename T2,
15643  typename T3, typename T4>
15645  T3 t3, T4 t4) const
15646  {
15647  return (new node_type(t1, t2, t3, t4));
15648  }
15649 
15650  template <typename node_type,
15651  typename T1, typename T2,
15652  typename T3, typename T4,
15653  typename T5>
15655  T3 t3, T4 t4,
15656  T5 t5) const
15657  {
15658  return (new node_type(t1, t2, t3, t4, t5));
15659  }
15660 
15661  template <typename node_type,
15662  typename T1, typename T2,
15663  typename T3, typename T4,
15664  typename T5, typename T6>
15666  T3 t3, T4 t4,
15667  T5 t5, T6 t6) const
15668  {
15669  return (new node_type(t1, t2, t3, t4, t5, t6));
15670  }
15671 
15672  template <typename node_type,
15673  typename T1, typename T2,
15674  typename T3, typename T4,
15675  typename T5, typename T6, typename T7>
15677  T3 t3, T4 t4,
15678  T5 t5, T6 t6,
15679  T7 t7) const
15680  {
15681  return (new node_type(t1, t2, t3, t4, t5, t6, t7));
15682  }
15683 
15684  template <typename T>
15685  void inline free(expression_node<T>*& e) const
15686  {
15687  delete e;
15688  e = 0;
15689  }
15690  };
15691 
15692  inline void load_operations_map(std::multimap<std::string,details::base_operation_t,details::ilesscompare>& m)
15693  {
15694  #define register_op(Symbol,Type,Args) \
15695  m.insert(std::make_pair(std::string(Symbol),details::base_operation_t(Type,Args))); \
15696 
15697  register_op( "abs", e_abs , 1)
15698  register_op( "acos", e_acos , 1)
15699  register_op( "acosh", e_acosh , 1)
15700  register_op( "asin", e_asin , 1)
15701  register_op( "asinh", e_asinh , 1)
15702  register_op( "atan", e_atan , 1)
15703  register_op( "atanh", e_atanh , 1)
15704  register_op( "ceil", e_ceil , 1)
15705  register_op( "cos", e_cos , 1)
15706  register_op( "cosh", e_cosh , 1)
15707  register_op( "exp", e_exp , 1)
15708  register_op( "expm1", e_expm1 , 1)
15709  register_op( "floor", e_floor , 1)
15710  register_op( "log", e_log , 1)
15711  register_op( "log10", e_log10 , 1)
15712  register_op( "log2", e_log2 , 1)
15713  register_op( "log1p", e_log1p , 1)
15714  register_op( "round", e_round , 1)
15715  register_op( "sin", e_sin , 1)
15716  register_op( "sinc", e_sinc , 1)
15717  register_op( "sinh", e_sinh , 1)
15718  register_op( "sec", e_sec , 1)
15719  register_op( "csc", e_csc , 1)
15720  register_op( "sqrt", e_sqrt , 1)
15721  register_op( "tan", e_tan , 1)
15722  register_op( "tanh", e_tanh , 1)
15723  register_op( "cot", e_cot , 1)
15724  register_op( "rad2deg", e_r2d , 1)
15725  register_op( "deg2rad", e_d2r , 1)
15726  register_op( "deg2grad", e_d2g , 1)
15727  register_op( "grad2deg", e_g2d , 1)
15728  register_op( "sgn", e_sgn , 1)
15729  register_op( "not", e_notl , 1)
15730  register_op( "erf", e_erf , 1)
15731  register_op( "erfc", e_erfc , 1)
15732  register_op( "ncdf", e_ncdf , 1)
15733  register_op( "frac", e_frac , 1)
15734  register_op( "trunc", e_trunc , 1)
15735  register_op( "atan2", e_atan2 , 2)
15736  register_op( "mod", e_mod , 2)
15737  register_op( "logn", e_logn , 2)
15738  register_op( "pow", e_pow , 2)
15739  register_op( "root", e_root , 2)
15740  register_op( "roundn", e_roundn , 2)
15741  register_op( "equal", e_equal , 2)
15742  register_op("not_equal", e_nequal , 2)
15743  register_op( "hypot", e_hypot , 2)
15744  register_op( "shr", e_shr , 2)
15745  register_op( "shl", e_shl , 2)
15746  register_op( "clamp", e_clamp , 3)
15747  register_op( "iclamp", e_iclamp , 3)
15748  register_op( "inrange", e_inrange , 3)
15749  #undef register_op
15750  }
15751 
15752  } // namespace details
15753 
15755  {
15756  public:
15757 
15759  : allow_zero_parameters_(false),
15760  has_side_effects_(true),
15761  min_num_args_(0),
15762  max_num_args_(std::numeric_limits<std::size_t>::max())
15763  {}
15764 
15765  inline bool& allow_zero_parameters()
15766  {
15767  return allow_zero_parameters_;
15768  }
15769 
15770  inline bool& has_side_effects()
15771  {
15772  return has_side_effects_;
15773  }
15774 
15775  std::size_t& min_num_args()
15776  {
15777  return min_num_args_;
15778  }
15779 
15780  std::size_t& max_num_args()
15781  {
15782  return max_num_args_;
15783  }
15784 
15785  private:
15786 
15789  std::size_t min_num_args_;
15790  std::size_t max_num_args_;
15791  };
15792 
15793  template <typename FunctionType>
15794  void enable_zero_parameters(FunctionType& func)
15795  {
15796  func.allow_zero_parameters() = true;
15797 
15798  if (0 != func.min_num_args())
15799  {
15800  func.min_num_args() = 0;
15801  }
15802  }
15803 
15804  template <typename FunctionType>
15805  void disable_zero_parameters(FunctionType& func)
15806  {
15807  func.allow_zero_parameters() = false;
15808  }
15809 
15810  template <typename FunctionType>
15811  void enable_has_side_effects(FunctionType& func)
15812  {
15813  func.has_side_effects() = true;
15814  }
15815 
15816  template <typename FunctionType>
15817  void disable_has_side_effects(FunctionType& func)
15818  {
15819  func.has_side_effects() = false;
15820  }
15821 
15822  template <typename FunctionType>
15823  void set_min_num_args(FunctionType& func, const std::size_t& num_args)
15824  {
15825  func.min_num_args() = num_args;
15826 
15827  if ((0 != func.min_num_args()) && func.allow_zero_parameters())
15828  func.allow_zero_parameters() = false;
15829  }
15830 
15831  template <typename FunctionType>
15832  void set_max_num_args(FunctionType& func, const std::size_t& num_args)
15833  {
15834  func.max_num_args() = num_args;
15835  }
15836 
15837  template <typename T>
15839  {
15840  public:
15841 
15842  explicit ifunction(const std::size_t& pc)
15843  : param_count(pc)
15844  {}
15845 
15846  virtual ~ifunction()
15847  {}
15848 
15849  #define empty_method_body \
15850  { \
15851  return std::numeric_limits<T>::quiet_NaN(); \
15852  } \
15853 
15854  inline virtual T operator() ()
15856 
15857  inline virtual T operator() (const T&)
15859 
15860  inline virtual T operator() (const T&,const T&)
15862 
15863  inline virtual T operator() (const T&, const T&, const T&)
15865 
15866  inline virtual T operator() (const T&, const T&, const T&, const T&)
15868 
15869  inline virtual T operator() (const T&, const T&, const T&, const T&, const T&)
15871 
15872  inline virtual T operator() (const T&, const T&, const T&, const T&, const T&, const T&)
15874 
15875  inline virtual T operator() (const T&, const T&, const T&, const T&, const T&, const T&, const T&)
15877 
15878  inline virtual T operator() (const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&)
15880 
15881  inline virtual T operator() (const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&)
15883 
15884  inline virtual T operator() (const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&)
15886 
15887  inline virtual T operator() (const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&,
15888  const T&)
15890 
15891  inline virtual T operator() (const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&,
15892  const T&, const T&)
15894 
15895  inline virtual T operator() (const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&,
15896  const T&, const T&, const T&)
15898 
15899  inline virtual T operator() (const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&,
15900  const T&, const T&, const T&, const T&)
15902 
15903  inline virtual T operator() (const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&,
15904  const T&, const T&, const T&, const T&, const T&)
15906 
15907  inline virtual T operator() (const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&,
15908  const T&, const T&, const T&, const T&, const T&, const T&)
15910 
15911  inline virtual T operator() (const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&,
15912  const T&, const T&, const T&, const T&, const T&, const T&, const T&)
15914 
15915  inline virtual T operator() (const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&,
15916  const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&)
15918 
15919  inline virtual T operator() (const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&,
15920  const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&)
15922 
15923  inline virtual T operator() (const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&,
15924  const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&, const T&)
15926 
15927  #undef empty_method_body
15928 
15929  std::size_t param_count;
15930  };
15931 
15932  template <typename T>
15934  {
15935  public:
15936 
15938  {}
15939 
15940  inline virtual T operator() (const std::vector<T>&)
15941  {
15942  exprtk_debug(("ivararg_function::operator() - Operator has not been overridden.\n"));
15943  return std::numeric_limits<T>::quiet_NaN();
15944  }
15945  };
15946 
15947  template <typename T>
15949  {
15950  public:
15951 
15953  {
15956  };
15957 
15958  typedef T type;
15961 
15962  igeneric_function(const std::string& param_seq = "", const return_type rtr_type = e_rtrn_scalar)
15963  : parameter_sequence(param_seq),
15964  rtrn_type(rtr_type)
15965  {}
15966 
15968  {}
15969 
15970  #define igeneric_function_empty_body(N) \
15971  { \
15972  exprtk_debug(("igeneric_function::operator() - Operator has not been overridden. ["#N"]\n")); \
15973  return std::numeric_limits<T>::quiet_NaN(); \
15974  } \
15975 
15976  // f(i_0,i_1,....,i_N) --> Scalar
15977  inline virtual T operator() (parameter_list_t)
15979 
15980  // f(i_0,i_1,....,i_N) --> String
15981  inline virtual T operator() (std::string&, parameter_list_t)
15983 
15984  // f(psi,i_0,i_1,....,i_N) --> Scalar
15985  inline virtual T operator() (const std::size_t&, parameter_list_t)
15987 
15988  // f(psi,i_0,i_1,....,i_N) --> String
15989  inline virtual T operator() (const std::size_t&, std::string&, parameter_list_t)
15991 
15992  std::string parameter_sequence;
15994  };
15995 
15996  template <typename T> class parser;
15997  template <typename T> class expression_helper;
15998 
15999  template <typename T>
16001  {
16002  public:
16003 
16004  typedef T (*ff00_functor)();
16005  typedef T (*ff01_functor)(T);
16006  typedef T (*ff02_functor)(T,T);
16007  typedef T (*ff03_functor)(T,T,T);
16008  typedef T (*ff04_functor)(T,T,T,T);
16009  typedef T (*ff05_functor)(T,T,T,T,T);
16010  typedef T (*ff06_functor)(T,T,T,T,T,T);
16011  typedef T (*ff07_functor)(T,T,T,T,T,T,T);
16012  typedef T (*ff08_functor)(T,T,T,T,T,T,T,T);
16013  typedef T (*ff09_functor)(T,T,T,T,T,T,T,T,T);
16014  typedef T (*ff10_functor)(T,T,T,T,T,T,T,T,T,T);
16015  typedef T (*ff11_functor)(T,T,T,T,T,T,T,T,T,T,T);
16016  typedef T (*ff12_functor)(T,T,T,T,T,T,T,T,T,T,T,T);
16017  typedef T (*ff13_functor)(T,T,T,T,T,T,T,T,T,T,T,T,T);
16018  typedef T (*ff14_functor)(T,T,T,T,T,T,T,T,T,T,T,T,T,T);
16019  typedef T (*ff15_functor)(T,T,T,T,T,T,T,T,T,T,T,T,T,T,T);
16020 
16021  protected:
16022 
16023  struct freefunc00 : public exprtk::ifunction<T>
16024  {
16026 
16027  freefunc00(ff00_functor ff) : exprtk::ifunction<T>(0), f(ff) {}
16028  inline T operator() ()
16029  { return f(); }
16030  ff00_functor f;
16031  };
16032 
16033  struct freefunc01 : public exprtk::ifunction<T>
16034  {
16036 
16037  freefunc01(ff01_functor ff) : exprtk::ifunction<T>(1), f(ff) {}
16038  inline T operator() (const T& v0)
16039  { return f(v0); }
16040  ff01_functor f;
16041  };
16042 
16043  struct freefunc02 : public exprtk::ifunction<T>
16044  {
16046 
16047  freefunc02(ff02_functor ff) : exprtk::ifunction<T>(2), f(ff) {}
16048  inline T operator() (const T& v0, const T& v1)
16049  { return f(v0, v1); }
16050  ff02_functor f;
16051  };
16052 
16053  struct freefunc03 : public exprtk::ifunction<T>
16054  {
16056 
16057  freefunc03(ff03_functor ff) : exprtk::ifunction<T>(3), f(ff) {}
16058  inline T operator() (const T& v0, const T& v1, const T& v2)
16059  { return f(v0, v1, v2); }
16060  ff03_functor f;
16061  };
16062 
16063  struct freefunc04 : public exprtk::ifunction<T>
16064  {
16066 
16067  freefunc04(ff04_functor ff) : exprtk::ifunction<T>(4), f(ff) {}
16068  inline T operator() (const T& v0, const T& v1, const T& v2, const T& v3)
16069  { return f(v0, v1, v2, v3); }
16070  ff04_functor f;
16071  };
16072 
16073  struct freefunc05 : public exprtk::ifunction<T>
16074  {
16076 
16077  freefunc05(ff05_functor ff) : exprtk::ifunction<T>(5), f(ff) {}
16078  inline T operator() (const T& v0, const T& v1, const T& v2, const T& v3, const T& v4)
16079  { return f(v0, v1, v2, v3, v4); }
16080  ff05_functor f;
16081  };
16082 
16083  struct freefunc06 : public exprtk::ifunction<T>
16084  {
16086 
16087  freefunc06(ff06_functor ff) : exprtk::ifunction<T>(6), f(ff) {}
16088  inline T operator() (const T& v0, const T& v1, const T& v2, const T& v3, const T& v4, const T& v5)
16089  { return f(v0, v1, v2, v3, v4, v5); }
16090  ff06_functor f;
16091  };
16092 
16093  struct freefunc07 : public exprtk::ifunction<T>
16094  {
16096 
16097  freefunc07(ff07_functor ff) : exprtk::ifunction<T>(7), f(ff) {}
16098  inline T operator() (const T& v0, const T& v1, const T& v2, const T& v3, const T& v4,
16099  const T& v5, const T& v6)
16100  { return f(v0, v1, v2, v3, v4, v5, v6); }
16101  ff07_functor f;
16102  };
16103 
16104  struct freefunc08 : public exprtk::ifunction<T>
16105  {
16107 
16108  freefunc08(ff08_functor ff) : exprtk::ifunction<T>(8), f(ff) {}
16109  inline T operator() (const T& v0, const T& v1, const T& v2, const T& v3, const T& v4,
16110  const T& v5, const T& v6, const T& v7)
16111  { return f(v0, v1, v2, v3, v4, v5, v6, v7); }
16112  ff08_functor f;
16113  };
16114 
16115  struct freefunc09 : public exprtk::ifunction<T>
16116  {
16118 
16119  freefunc09(ff09_functor ff) : exprtk::ifunction<T>(9), f(ff) {}
16120  inline T operator() (const T& v0, const T& v1, const T& v2, const T& v3, const T& v4,
16121  const T& v5, const T& v6, const T& v7, const T& v8)
16122  { return f(v0, v1, v2, v3, v4, v5, v6, v7, v8); }
16123  ff09_functor f;
16124  };
16125 
16126  struct freefunc10 : public exprtk::ifunction<T>
16127  {
16129 
16130  freefunc10(ff10_functor ff) : exprtk::ifunction<T>(10), f(ff) {}
16131  inline T operator() (const T& v0, const T& v1, const T& v2, const T& v3, const T& v4,
16132  const T& v5, const T& v6, const T& v7, const T& v8, const T& v9)
16133  { return f(v0, v1, v2, v3, v4, v5, v6, v7, v8, v9); }
16134  ff10_functor f;
16135  };
16136 
16137  struct freefunc11 : public exprtk::ifunction<T>
16138  {
16140 
16141  freefunc11(ff11_functor ff) : exprtk::ifunction<T>(11), f(ff) {}
16142  inline T operator() (const T& v0, const T& v1, const T& v2, const T& v3, const T& v4,
16143  const T& v5, const T& v6, const T& v7, const T& v8, const T& v9, const T& v10)
16144  { return f(v0, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10); }
16145  ff11_functor f;
16146  };
16147 
16148  struct freefunc12 : public exprtk::ifunction<T>
16149  {
16151 
16152  freefunc12(ff12_functor ff) : exprtk::ifunction<T>(12), f(ff) {}
16153  inline T operator() (const T& v00, const T& v01, const T& v02, const T& v03, const T& v04,
16154  const T& v05, const T& v06, const T& v07, const T& v08, const T& v09,
16155  const T& v10, const T& v11)
16156  { return f(v00, v01, v02, v03, v04, v05, v06, v07, v08, v09, v10, v11); }
16157  ff12_functor f;
16158  };
16159 
16160  struct freefunc13 : public exprtk::ifunction<T>
16161  {
16163 
16164  freefunc13(ff13_functor ff) : exprtk::ifunction<T>(13), f(ff) {}
16165  inline T operator() (const T& v00, const T& v01, const T& v02, const T& v03, const T& v04,
16166  const T& v05, const T& v06, const T& v07, const T& v08, const T& v09,
16167  const T& v10, const T& v11, const T& v12)
16168  { return f(v00, v01, v02, v03, v04, v05, v06, v07, v08, v09, v10, v11, v12); }
16169  ff13_functor f;
16170  };
16171 
16172  struct freefunc14 : public exprtk::ifunction<T>
16173  {
16175 
16176  freefunc14(ff14_functor ff) : exprtk::ifunction<T>(14), f(ff) {}
16177  inline T operator() (const T& v00, const T& v01, const T& v02, const T& v03, const T& v04,
16178  const T& v05, const T& v06, const T& v07, const T& v08, const T& v09,
16179  const T& v10, const T& v11, const T& v12, const T& v13)
16180  { return f(v00, v01, v02, v03, v04, v05, v06, v07, v08, v09, v10, v11, v12, v13); }
16181  ff14_functor f;
16182  };
16183 
16184  struct freefunc15 : public exprtk::ifunction<T>
16185  {
16187 
16188  freefunc15(ff15_functor ff) : exprtk::ifunction<T>(15), f(ff) {}
16189  inline T operator() (const T& v00, const T& v01, const T& v02, const T& v03, const T& v04,
16190  const T& v05, const T& v06, const T& v07, const T& v08, const T& v09,
16191  const T& v10, const T& v11, const T& v12, const T& v13, const T& v14)
16192  { return f(v00, v01, v02, v03, v04, v05, v06, v07, v08, v09, v10, v11, v12, v13, v14); }
16193  ff15_functor f;
16194  };
16195 
16196  template <typename Type, typename RawType>
16197  struct type_store
16198  {
16205  #ifndef exprtk_disable_string_capabilities
16207  #endif
16208 
16209  typedef Type type_t;
16210  typedef type_t* type_ptr;
16211  typedef std::pair<bool,type_ptr> type_pair_t;
16212  typedef std::map<std::string,type_pair_t,details::ilesscompare> type_map_t;
16213  typedef typename type_map_t::iterator tm_itr_t;
16214  typedef typename type_map_t::const_iterator tm_const_itr_t;
16215 
16216  enum { lut_size = 256 };
16217 
16219  std::size_t size;
16220 
16222  : size(0)
16223  {}
16224 
16225  inline bool symbol_exists(const std::string& symbol_name) const
16226  {
16227  if (symbol_name.empty())
16228  return false;
16229  else if (map.end() != map.find(symbol_name))
16230  return true;
16231  else
16232  return false;
16233  }
16234 
16235  template <typename PtrType>
16236  inline std::string entity_name(const PtrType& ptr) const
16237  {
16238  if (map.empty())
16239  return std::string();
16240 
16241  tm_const_itr_t itr = map.begin();
16242 
16243  while (map.end() != itr)
16244  {
16245  if (itr->second.second == ptr)
16246  {
16247  return itr->first;
16248  }
16249  else
16250  ++itr;
16251  }
16252 
16253  return std::string();
16254  }
16255 
16256  inline bool is_constant(const std::string& symbol_name) const
16257  {
16258  if (symbol_name.empty())
16259  return false;
16260  else
16261  {
16262  const tm_const_itr_t itr = map.find(symbol_name);
16263 
16264  if (map.end() == itr)
16265  return false;
16266  else
16267  return (*itr).second.first;
16268  }
16269  }
16270 
16271  template <typename Tie, typename RType>
16272  inline bool add_impl(const std::string& symbol_name, RType t, const bool is_const)
16273  {
16274  if (symbol_name.size() > 1)
16275  {
16276  for (std::size_t i = 0; i < details::reserved_symbols_size; ++i)
16277  {
16278  if (details::imatch(symbol_name, details::reserved_symbols[i]))
16279  {
16280  return false;
16281  }
16282  }
16283  }
16284 
16285  const tm_itr_t itr = map.find(symbol_name);
16286 
16287  if (map.end() == itr)
16288  {
16289  map[symbol_name] = Tie::make(t,is_const);
16290  ++size;
16291  }
16292 
16293  return true;
16294  }
16295 
16296  struct tie_array
16297  {
16298  static inline std::pair<bool,vector_t*> make(std::pair<T*,std::size_t> v, const bool is_const = false)
16299  {
16300  return std::make_pair(is_const, new vector_t(v.first, v.second));
16301  }
16302  };
16303 
16304  struct tie_stdvec
16305  {
16306  template <typename Allocator>
16307  static inline std::pair<bool,vector_t*> make(std::vector<T,Allocator>& v, const bool is_const = false)
16308  {
16309  return std::make_pair(is_const, new vector_t(v));
16310  }
16311  };
16312 
16314  {
16315  static inline std::pair<bool,vector_t*> make(exprtk::vector_view<T>& v, const bool is_const = false)
16316  {
16317  return std::make_pair(is_const, new vector_t(v));
16318  }
16319  };
16320 
16321  struct tie_stddeq
16322  {
16323  template <typename Allocator>
16324  static inline std::pair<bool,vector_t*> make(std::deque<T,Allocator>& v, const bool is_const = false)
16325  {
16326  return std::make_pair(is_const, new vector_t(v));
16327  }
16328  };
16329 
16330  template <std::size_t v_size>
16331  inline bool add(const std::string& symbol_name, T (&v)[v_size], const bool is_const = false)
16332  {
16333  return add_impl<tie_array,std::pair<T*,std::size_t> >
16334  (symbol_name, std::make_pair(v,v_size), is_const);
16335  }
16336 
16337  inline bool add(const std::string& symbol_name, T* v, const std::size_t v_size, const bool is_const = false)
16338  {
16339  return add_impl<tie_array,std::pair<T*,std::size_t> >
16340  (symbol_name, std::make_pair(v,v_size), is_const);
16341  }
16342 
16343  template <typename Allocator>
16344  inline bool add(const std::string& symbol_name, std::vector<T,Allocator>& v, const bool is_const = false)
16345  {
16346  return add_impl<tie_stdvec,std::vector<T,Allocator>&>
16347  (symbol_name, v, is_const);
16348  }
16349 
16350  inline bool add(const std::string& symbol_name, exprtk::vector_view<T>& v, const bool is_const = false)
16351  {
16352  return add_impl<tie_vecview,exprtk::vector_view<T>&>
16353  (symbol_name, v, is_const);
16354  }
16355 
16356  template <typename Allocator>
16357  inline bool add(const std::string& symbol_name, std::deque<T,Allocator>& v, const bool is_const = false)
16358  {
16359  return add_impl<tie_stddeq,std::deque<T,Allocator>&>
16360  (symbol_name, v, is_const);
16361  }
16362 
16363  inline bool add(const std::string& symbol_name, RawType& t, const bool is_const = false)
16364  {
16365  struct tie
16366  {
16367  static inline std::pair<bool,variable_node_t*> make(T& t,const bool is_const = false)
16368  {
16369  return std::make_pair(is_const, new variable_node_t(t));
16370  }
16371 
16372  #ifndef exprtk_disable_string_capabilities
16373  static inline std::pair<bool,stringvar_node_t*> make(std::string& t,const bool is_const = false)
16374  {
16375  return std::make_pair(is_const, new stringvar_node_t(t));
16376  }
16377  #endif
16378 
16379  static inline std::pair<bool,function_t*> make(function_t& t, const bool is_constant = false)
16380  {
16381  return std::make_pair(is_constant,&t);
16382  }
16383 
16384  static inline std::pair<bool,vararg_function_t*> make(vararg_function_t& t, const bool is_const = false)
16385  {
16386  return std::make_pair(is_const,&t);
16387  }
16388 
16389  static inline std::pair<bool,generic_function_t*> make(generic_function_t& t, const bool is_constant = false)
16390  {
16391  return std::make_pair(is_constant,&t);
16392  }
16393  };
16394 
16395  const tm_itr_t itr = map.find(symbol_name);
16396 
16397  if (map.end() == itr)
16398  {
16399  map[symbol_name] = tie::make(t,is_const);
16400  ++size;
16401  }
16402 
16403  return true;
16404  }
16405 
16406  inline type_ptr get(const std::string& symbol_name) const
16407  {
16408  const tm_const_itr_t itr = map.find(symbol_name);
16409 
16410  if (map.end() == itr)
16411  return reinterpret_cast<type_ptr>(0);
16412  else
16413  return itr->second.second;
16414  }
16415 
16416  template <typename TType, typename TRawType, typename PtrType>
16417  struct ptr_match
16418  {
16419  static inline bool test(const PtrType, const void*)
16420  {
16421  return false;
16422  }
16423  };
16424 
16425  template <typename TType, typename TRawType>
16426  struct ptr_match<TType,TRawType,variable_node_t*>
16427  {
16428  static inline bool test(const variable_node_t* p, const void* ptr)
16429  {
16430  exprtk_debug(("ptr_match::test() - %p <--> %p\n",(void*)(&(p->ref())),ptr));
16431  return (&(p->ref()) == ptr);
16432  }
16433  };
16434 
16435  inline type_ptr get_from_varptr(const void* ptr) const
16436  {
16437  tm_const_itr_t itr = map.begin();
16438 
16439  while (map.end() != itr)
16440  {
16441  type_ptr ret_ptr = itr->second.second;
16442 
16443  if (ptr_match<Type,RawType,type_ptr>::test(ret_ptr,ptr))
16444  {
16445  return ret_ptr;
16446  }
16447 
16448  ++itr;
16449  }
16450 
16451  return type_ptr(0);
16452  }
16453 
16454  inline bool remove(const std::string& symbol_name, const bool delete_node = true)
16455  {
16456  const tm_itr_t itr = map.find(symbol_name);
16457 
16458  if (map.end() != itr)
16459  {
16460  struct deleter
16461  {
16462  static inline void process(std::pair<bool,variable_node_t*>& n) { delete n.second; }
16463  static inline void process(std::pair<bool,vector_t*>& n) { delete n.second; }
16464  #ifndef exprtk_disable_string_capabilities
16465  static inline void process(std::pair<bool,stringvar_node_t*>& n) { delete n.second; }
16466  #endif
16467  static inline void process(std::pair<bool,function_t*>&) { }
16468  };
16469 
16470  if (delete_node)
16471  {
16472  deleter::process((*itr).second);
16473  }
16474 
16475  map.erase(itr);
16476  --size;
16477 
16478  return true;
16479  }
16480  else
16481  return false;
16482  }
16483 
16484  inline RawType& type_ref(const std::string& symbol_name)
16485  {
16486  struct init_type
16487  {
16488  static inline double set(double) { return (0.0); }
16489  static inline double set(long double) { return (0.0); }
16490  static inline float set(float) { return (0.0f); }
16491  static inline std::string set(std::string) { return std::string(""); }
16492  };
16493 
16494  static RawType null_type = init_type::set(RawType());
16495 
16496  const tm_const_itr_t itr = map.find(symbol_name);
16497 
16498  if (map.end() == itr)
16499  return null_type;
16500  else
16501  return itr->second.second->ref();
16502  }
16503 
16504  inline void clear(const bool delete_node = true)
16505  {
16506  struct deleter
16507  {
16508  static inline void process(std::pair<bool,variable_node_t*>& n) { delete n.second; }
16509  static inline void process(std::pair<bool,vector_t*>& n) { delete n.second; }
16510  static inline void process(std::pair<bool,function_t*>&) { }
16511  #ifndef exprtk_disable_string_capabilities
16512  static inline void process(std::pair<bool,stringvar_node_t*>& n) { delete n.second; }
16513  #endif
16514  };
16515 
16516  if (!map.empty())
16517  {
16518  if (delete_node)
16519  {
16520  tm_itr_t itr = map.begin();
16521  tm_itr_t end = map.end ();
16522 
16523  while (end != itr)
16524  {
16525  deleter::process((*itr).second);
16526  ++itr;
16527  }
16528  }
16529 
16530  map.clear();
16531  }
16532 
16533  size = 0;
16534  }
16535 
16536  template <typename Allocator,
16537  template <typename, typename> class Sequence>
16538  inline std::size_t get_list(Sequence<std::pair<std::string,RawType>,Allocator>& list) const
16539  {
16540  std::size_t count = 0;
16541 
16542  if (!map.empty())
16543  {
16544  tm_const_itr_t itr = map.begin();
16545  tm_const_itr_t end = map.end ();
16546 
16547  while (end != itr)
16548  {
16549  list.push_back(std::make_pair((*itr).first,itr->second.second->ref()));
16550  ++itr;
16551  ++count;
16552  }
16553  }
16554 
16555  return count;
16556  }
16557 
16558  template <typename Allocator,
16559  template <typename, typename> class Sequence>
16560  inline std::size_t get_list(Sequence<std::string,Allocator>& vlist) const
16561  {
16562  std::size_t count = 0;
16563 
16564  if (!map.empty())
16565  {
16566  tm_const_itr_t itr = map.begin();
16567  tm_const_itr_t end = map.end ();
16568 
16569  while (end != itr)
16570  {
16571  vlist.push_back((*itr).first);
16572  ++itr;
16573  ++count;
16574  }
16575  }
16576 
16577  return count;
16578  }
16579  };
16580 
16584  typedef variable_t* variable_ptr;
16585  #ifndef exprtk_disable_string_capabilities
16587  typedef stringvar_t* stringvar_ptr;
16588  #endif
16592  typedef function_t* function_ptr;
16593  typedef vararg_function_t* vararg_function_ptr;
16594  typedef generic_function_t* generic_function_ptr;
16595 
16596  static const std::size_t lut_size = 256;
16597 
16598  // Symbol Table Holder
16600  {
16601  struct st_data
16602  {
16604  #ifndef exprtk_disable_string_capabilities
16606  #endif
16612 
16614  {
16615  for (std::size_t i = 0; i < details::reserved_words_size; ++i)
16616  {
16617  reserved_symbol_table_.insert(details::reserved_words[i]);
16618  }
16619 
16620  for (std::size_t i = 0; i < details::reserved_symbols_size; ++i)
16621  {
16622  reserved_symbol_table_.insert(details::reserved_symbols[i]);
16623  }
16624  }
16625 
16627  {
16628  for (std::size_t i = 0; i < free_function_list_.size(); ++i)
16629  {
16630  delete free_function_list_[i];
16631  }
16632  }
16633 
16634  inline bool is_reserved_symbol(const std::string& symbol) const
16635  {
16636  return (reserved_symbol_table_.end() != reserved_symbol_table_.find(symbol));
16637  }
16638 
16639  static inline st_data* create()
16640  {
16641  return (new st_data);
16642  }
16643 
16644  static inline void destroy(st_data*& sd)
16645  {
16646  delete sd;
16647  sd = reinterpret_cast<st_data*>(0);
16648  }
16649 
16650  std::list<T> local_symbol_list_;
16651  std::list<std::string> local_stringvar_list_;
16652  std::set<std::string> reserved_symbol_table_;
16653  std::vector<ifunction<T>*> free_function_list_;
16654  };
16655 
16657  : ref_count(1),
16658  data_(st_data::create())
16659  {}
16660 
16662  : ref_count(1),
16663  data_(data)
16664  {}
16665 
16667  {
16668  if (data_ && (0 == ref_count))
16669  {
16670  st_data::destroy(data_);
16671  }
16672  }
16673 
16674  static inline control_block* create()
16675  {
16676  return (new control_block);
16677  }
16678 
16679  template <typename SymTab>
16680  static inline void destroy(control_block*& cntrl_blck, SymTab* sym_tab)
16681  {
16682  if (cntrl_blck)
16683  {
16684  if (
16685  (0 != cntrl_blck->ref_count) &&
16686  (0 == --cntrl_blck->ref_count)
16687  )
16688  {
16689  if (sym_tab)
16690  sym_tab->clear();
16691 
16692  delete cntrl_blck;
16693  }
16694 
16695  cntrl_blck = 0;
16696  }
16697  }
16698 
16699  std::size_t ref_count;
16701  };
16702 
16703  public:
16704 
16706  : control_block_(control_block::create())
16707  {
16708  clear();
16709  }
16710 
16712  {
16713  control_block::destroy(control_block_,this);
16714  }
16715 
16717  {
16718  control_block_ = st.control_block_;
16719  control_block_->ref_count++;
16720  }
16721 
16723  {
16724  if (this != &st)
16725  {
16726  control_block::destroy(control_block_,reinterpret_cast<symbol_table<T>*>(0));
16727 
16728  control_block_ = st.control_block_;
16729  control_block_->ref_count++;
16730  }
16731 
16732  return (*this);
16733  }
16734 
16735  inline bool operator==(const symbol_table<T>& st) const
16736  {
16737  return (this == &st) || (control_block_ == st.control_block_);
16738  }
16739 
16740  inline void clear_variables(const bool delete_node = true)
16741  {
16742  local_data().variable_store.clear(delete_node);
16743  }
16744 
16745  inline void clear_functions()
16746  {
16747  local_data().function_store.clear();
16748  }
16749 
16750  inline void clear_strings()
16751  {
16752  #ifndef exprtk_disable_string_capabilities
16753  local_data().stringvar_store.clear();
16754  #endif
16755  }
16756 
16757  inline void clear_vectors()
16758  {
16759  local_data().vector_store.clear();
16760  }
16761 
16763  {
16764  local_data().local_symbol_list_.clear();
16765  }
16766 
16767  inline void clear()
16768  {
16769  if (!valid()) return;
16770  clear_variables ();
16771  clear_functions ();
16772  clear_strings ();
16773  clear_vectors ();
16774  clear_local_constants();
16775  }
16776 
16777  inline std::size_t variable_count() const
16778  {
16779  if (valid())
16780  return local_data().variable_store.size;
16781  else
16782  return 0;
16783  }
16784 
16785  #ifndef exprtk_disable_string_capabilities
16786  inline std::size_t stringvar_count() const
16787  {
16788  if (valid())
16789  return local_data().stringvar_store.size;
16790  else
16791  return 0;
16792  }
16793  #endif
16794 
16795  inline std::size_t function_count() const
16796  {
16797  if (valid())
16798  return local_data().function_store.size;
16799  else
16800  return 0;
16801  }
16802 
16803  inline std::size_t vector_count() const
16804  {
16805  if (valid())
16806  return local_data().vector_store.size;
16807  else
16808  return 0;
16809  }
16810 
16811  inline variable_ptr get_variable(const std::string& variable_name) const
16812  {
16813  if (!valid())
16814  return reinterpret_cast<variable_ptr>(0);
16815  else if (!valid_symbol(variable_name))
16816  return reinterpret_cast<variable_ptr>(0);
16817  else
16818  return local_data().variable_store.get(variable_name);
16819  }
16820 
16821  inline variable_ptr get_variable(const T& var_ref) const
16822  {
16823  if (!valid())
16824  return reinterpret_cast<variable_ptr>(0);
16825  else
16826  return local_data().variable_store.get_from_varptr(
16827  reinterpret_cast<const void*>(&var_ref));
16828  }
16829 
16830  #ifndef exprtk_disable_string_capabilities
16831  inline stringvar_ptr get_stringvar(const std::string& string_name) const
16832  {
16833  if (!valid())
16834  return reinterpret_cast<stringvar_ptr>(0);
16835  else if (!valid_symbol(string_name))
16836  return reinterpret_cast<stringvar_ptr>(0);
16837  else
16838  return local_data().stringvar_store.get(string_name);
16839  }
16840  #endif
16841 
16842  inline function_ptr get_function(const std::string& function_name) const
16843  {
16844  if (!valid())
16845  return reinterpret_cast<function_ptr>(0);
16846  else if (!valid_symbol(function_name))
16847  return reinterpret_cast<function_ptr>(0);
16848  else
16849  return local_data().function_store.get(function_name);
16850  }
16851 
16852  inline vararg_function_ptr get_vararg_function(const std::string& vararg_function_name) const
16853  {
16854  if (!valid())
16855  return reinterpret_cast<vararg_function_ptr>(0);
16856  else if (!valid_symbol(vararg_function_name))
16857  return reinterpret_cast<vararg_function_ptr>(0);
16858  else
16859  return local_data().vararg_function_store.get(vararg_function_name);
16860  }
16861 
16862  inline generic_function_ptr get_generic_function(const std::string& function_name) const
16863  {
16864  if (!valid())
16865  return reinterpret_cast<generic_function_ptr>(0);
16866  else if (!valid_symbol(function_name))
16867  return reinterpret_cast<generic_function_ptr>(0);
16868  else
16869  return local_data().generic_function_store.get(function_name);
16870  }
16871 
16872  inline generic_function_ptr get_string_function(const std::string& function_name) const
16873  {
16874  if (!valid())
16875  return reinterpret_cast<generic_function_ptr>(0);
16876  else if (!valid_symbol(function_name))
16877  return reinterpret_cast<generic_function_ptr>(0);
16878  else
16879  return local_data().string_function_store.get(function_name);
16880  }
16881 
16882  typedef vector_holder_t* vector_holder_ptr;
16883 
16884  inline vector_holder_ptr get_vector(const std::string& vector_name) const
16885  {
16886  if (!valid())
16887  return reinterpret_cast<vector_holder_ptr>(0);
16888  else if (!valid_symbol(vector_name))
16889  return reinterpret_cast<vector_holder_ptr>(0);
16890  else
16891  return local_data().vector_store.get(vector_name);
16892  }
16893 
16894  inline T& variable_ref(const std::string& symbol_name)
16895  {
16896  static T null_var = T(0);
16897  if (!valid())
16898  return null_var;
16899  else if (!valid_symbol(symbol_name))
16900  return null_var;
16901  else
16902  return local_data().variable_store.type_ref(symbol_name);
16903  }
16904 
16905  #ifndef exprtk_disable_string_capabilities
16906  inline std::string& stringvar_ref(const std::string& symbol_name)
16907  {
16908  static std::string null_stringvar;
16909  if (!valid())
16910  return null_stringvar;
16911  else if (!valid_symbol(symbol_name))
16912  return null_stringvar;
16913  else
16914  return local_data().stringvar_store.type_ref(symbol_name);
16915  }
16916  #endif
16917 
16918  inline bool is_constant_node(const std::string& symbol_name) const
16919  {
16920  if (!valid())
16921  return false;
16922  else if (!valid_symbol(symbol_name))
16923  return false;
16924  else
16925  return local_data().variable_store.is_constant(symbol_name);
16926  }
16927 
16928  #ifndef exprtk_disable_string_capabilities
16929  inline bool is_constant_string(const std::string& symbol_name) const
16930  {
16931  if (!valid())
16932  return false;
16933  else if (!valid_symbol(symbol_name))
16934  return false;
16935  else if (!local_data().stringvar_store.symbol_exists(symbol_name))
16936  return false;
16937  else
16938  return local_data().stringvar_store.is_constant(symbol_name);
16939  }
16940  #endif
16941 
16942  inline bool create_variable(const std::string& variable_name, const T& value = T(0))
16943  {
16944  if (!valid())
16945  return false;
16946  else if (!valid_symbol(variable_name))
16947  return false;
16948  else if (symbol_exists(variable_name))
16949  return false;
16950 
16951  local_data().local_symbol_list_.push_back(value);
16952  T& t = local_data().local_symbol_list_.back();
16953 
16954  return add_variable(variable_name,t);
16955  }
16956 
16957  #ifndef exprtk_disable_string_capabilities
16958  inline bool create_stringvar(const std::string& stringvar_name, const std::string& value = std::string(""))
16959  {
16960  if (!valid())
16961  return false;
16962  else if (!valid_symbol(stringvar_name))
16963  return false;
16964  else if (symbol_exists(stringvar_name))
16965  return false;
16966 
16967  local_data().local_stringvar_list_.push_back(value);
16968  std::string& s = local_data().local_stringvar_list_.back();
16969 
16970  return add_stringvar(stringvar_name,s);
16971  }
16972  #endif
16973 
16974  inline bool add_variable(const std::string& variable_name, T& t, const bool is_constant = false)
16975  {
16976  if (!valid())
16977  return false;
16978  else if (!valid_symbol(variable_name))
16979  return false;
16980  else if (symbol_exists(variable_name))
16981  return false;
16982  else
16983  return local_data().variable_store.add(variable_name,t,is_constant);
16984  }
16985 
16986  inline bool add_constant(const std::string& constant_name, const T& value)
16987  {
16988  if (!valid())
16989  return false;
16990  else if (!valid_symbol(constant_name))
16991  return false;
16992  else if (symbol_exists(constant_name))
16993  return false;
16994 
16995  local_data().local_symbol_list_.push_back(value);
16996  T& t = local_data().local_symbol_list_.back();
16997 
16998  return add_variable(constant_name,t,true);
16999  }
17000 
17001  #ifndef exprtk_disable_string_capabilities
17002  inline bool add_stringvar(const std::string& stringvar_name, std::string& s, const bool is_constant = false)
17003  {
17004  if (!valid())
17005  return false;
17006  else if (!valid_symbol(stringvar_name))
17007  return false;
17008  else if (symbol_exists(stringvar_name))
17009  return false;
17010  else
17011  return local_data().stringvar_store.add(stringvar_name,s,is_constant);
17012  }
17013  #endif
17014 
17015  inline bool add_function(const std::string& function_name, function_t& function)
17016  {
17017  if (!valid())
17018  return false;
17019  else if (!valid_symbol(function_name))
17020  return false;
17021  else if (symbol_exists(function_name))
17022  return false;
17023  else
17024  return local_data().function_store.add(function_name,function);
17025  }
17026 
17027  inline bool add_function(const std::string& vararg_function_name, vararg_function_t& vararg_function)
17028  {
17029  if (!valid())
17030  return false;
17031  else if (!valid_symbol(vararg_function_name))
17032  return false;
17033  else if (symbol_exists(vararg_function_name))
17034  return false;
17035  else
17036  return local_data().vararg_function_store.add(vararg_function_name,vararg_function);
17037  }
17038 
17039  inline bool add_function(const std::string& function_name, generic_function_t& function)
17040  {
17041  if (!valid())
17042  return false;
17043  else if (!valid_symbol(function_name))
17044  return false;
17045  else if (symbol_exists(function_name))
17046  return false;
17047  else if (std::string::npos != function.parameter_sequence.find_first_not_of("STVZ*?|"))
17048  return false;
17049  else if (generic_function_t::e_rtrn_scalar == function.rtrn_type)
17050  return local_data().generic_function_store.add(function_name,function);
17051  else if (generic_function_t::e_rtrn_string == function.rtrn_type)
17052  return local_data().string_function_store.add(function_name, function);
17053  else
17054  return false;
17055  }
17056 
17057  #define exprtk_define_freefunction(NN) \
17058  inline bool add_function(const std::string& function_name, ff##NN##_functor function) \
17059  { \
17060  if (!valid()) \
17061  { return false; } \
17062  if (!valid_symbol(function_name)) \
17063  { return false; } \
17064  if (symbol_exists(function_name)) \
17065  { return false; } \
17066  \
17067  exprtk::ifunction<T>* ifunc = new freefunc##NN(function); \
17068  \
17069  local_data().free_function_list_.push_back(ifunc); \
17070  \
17071  return add_function(function_name,(*local_data().free_function_list_.back())); \
17072  } \
17073 
17082 
17083  #undef exprtk_define_freefunction
17084 
17085  inline bool add_reserved_function(const std::string& function_name, function_t& function)
17086  {
17087  if (!valid())
17088  return false;
17089  else if (!valid_symbol(function_name,false))
17090  return false;
17091  else if (symbol_exists(function_name,false))
17092  return false;
17093  else
17094  return local_data().function_store.add(function_name,function);
17095  }
17096 
17097  inline bool add_reserved_function(const std::string& vararg_function_name, vararg_function_t& vararg_function)
17098  {
17099  if (!valid())
17100  return false;
17101  else if (!valid_symbol(vararg_function_name,false))
17102  return false;
17103  else if (symbol_exists(vararg_function_name,false))
17104  return false;
17105  else
17106  return local_data().vararg_function_store.add(vararg_function_name,vararg_function);
17107  }
17108 
17109  inline bool add_reserved_function(const std::string& function_name, generic_function_t& function)
17110  {
17111  if (!valid())
17112  return false;
17113  else if (!valid_symbol(function_name,false))
17114  return false;
17115  else if (symbol_exists(function_name,false))
17116  return false;
17117  else if (std::string::npos != function.parameter_sequence.find_first_not_of("STV*?|"))
17118  return false;
17119  else if (generic_function_t::e_rtrn_scalar == function.rtrn_type)
17120  return local_data().generic_function_store.add(function_name,function);
17121  else if (generic_function_t::e_rtrn_string == function.rtrn_type)
17122  return local_data().string_function_store.add(function_name, function);
17123  else
17124  return false;
17125  }
17126 
17127  template <std::size_t N>
17128  inline bool add_vector(const std::string& vector_name, T (&v)[N])
17129  {
17130  if (!valid())
17131  return false;
17132  else if (!valid_symbol(vector_name))
17133  return false;
17134  else if (symbol_exists(vector_name))
17135  return false;
17136  else
17137  return local_data().vector_store.add(vector_name,v);
17138  }
17139 
17140  inline bool add_vector(const std::string& vector_name, T* v, const std::size_t& v_size)
17141  {
17142  if (!valid())
17143  return false;
17144  else if (!valid_symbol(vector_name))
17145  return false;
17146  else if (symbol_exists(vector_name))
17147  return false;
17148  else if (0 == v_size)
17149  return false;
17150  else
17151  return local_data().vector_store.add(vector_name,v,v_size);
17152  }
17153 
17154  template <typename Allocator>
17155  inline bool add_vector(const std::string& vector_name, std::vector<T,Allocator>& v)
17156  {
17157  if (!valid())
17158  return false;
17159  else if (!valid_symbol(vector_name))
17160  return false;
17161  else if (symbol_exists(vector_name))
17162  return false;
17163  else if (0 == v.size())
17164  return false;
17165  else
17166  return local_data().vector_store.add(vector_name,v);
17167  }
17168 
17169  inline bool add_vector(const std::string& vector_name, exprtk::vector_view<T>& v)
17170  {
17171  if (!valid())
17172  return false;
17173  else if (!valid_symbol(vector_name))
17174  return false;
17175  else if (symbol_exists(vector_name))
17176  return false;
17177  else if (0 == v.size())
17178  return false;
17179  else
17180  return local_data().vector_store.add(vector_name,v);
17181  }
17182 
17183  inline bool remove_variable(const std::string& variable_name, const bool delete_node = true)
17184  {
17185  if (!valid())
17186  return false;
17187  else
17188  return local_data().variable_store.remove(variable_name, delete_node);
17189  }
17190 
17191  #ifndef exprtk_disable_string_capabilities
17192  inline bool remove_stringvar(const std::string& string_name)
17193  {
17194  if (!valid())
17195  return false;
17196  else
17197  return local_data().stringvar_store.remove(string_name);
17198  }
17199  #endif
17200 
17201  inline bool remove_function(const std::string& function_name)
17202  {
17203  if (!valid())
17204  return false;
17205  else
17206  return local_data().function_store.remove(function_name);
17207  }
17208 
17209  inline bool remove_vararg_function(const std::string& vararg_function_name)
17210  {
17211  if (!valid())
17212  return false;
17213  else
17214  return local_data().vararg_function_store.remove(vararg_function_name);
17215  }
17216 
17217  inline bool remove_vector(const std::string& vector_name)
17218  {
17219  if (!valid())
17220  return false;
17221  else
17222  return local_data().vector_store.remove(vector_name);
17223  }
17224 
17225  inline bool add_constants()
17226  {
17227  return add_pi () &&
17228  add_epsilon () &&
17229  add_infinity() ;
17230  }
17231 
17232  inline bool add_pi()
17233  {
17234  const typename details::numeric::details::number_type<T>::type num_type;
17235  static const T local_pi = details::numeric::details::const_pi_impl<T>(num_type);
17236  return add_constant("pi",local_pi);
17237  }
17238 
17239  inline bool add_epsilon()
17240  {
17241  static const T local_epsilon = details::numeric::details::epsilon_type<T>::value();
17242  return add_constant("epsilon",local_epsilon);
17243  }
17244 
17245  inline bool add_infinity()
17246  {
17247  static const T local_infinity = std::numeric_limits<T>::infinity();
17248  return add_constant("inf",local_infinity);
17249  }
17250 
17251  template <typename Package>
17252  inline bool add_package(Package& package)
17253  {
17254  return package.register_package(*this);
17255  }
17256 
17257  template <typename Allocator,
17258  template <typename, typename> class Sequence>
17259  inline std::size_t get_variable_list(Sequence<std::pair<std::string,T>,Allocator>& vlist) const
17260  {
17261  if (!valid())
17262  return 0;
17263  else
17264  return local_data().variable_store.get_list(vlist);
17265  }
17266 
17267  template <typename Allocator,
17268  template <typename, typename> class Sequence>
17269  inline std::size_t get_variable_list(Sequence<std::string,Allocator>& vlist) const
17270  {
17271  if (!valid())
17272  return 0;
17273  else
17274  return local_data().variable_store.get_list(vlist);
17275  }
17276 
17277  #ifndef exprtk_disable_string_capabilities
17278  template <typename Allocator,
17279  template <typename, typename> class Sequence>
17280  inline std::size_t get_stringvar_list(Sequence<std::pair<std::string,std::string>,Allocator>& svlist) const
17281  {
17282  if (!valid())
17283  return 0;
17284  else
17285  return local_data().stringvar_store.get_list(svlist);
17286  }
17287 
17288  template <typename Allocator,
17289  template <typename, typename> class Sequence>
17290  inline std::size_t get_stringvar_list(Sequence<std::string,Allocator>& svlist) const
17291  {
17292  if (!valid())
17293  return 0;
17294  else
17295  return local_data().stringvar_store.get_list(svlist);
17296  }
17297  #endif
17298 
17299  template <typename Allocator,
17300  template <typename, typename> class Sequence>
17301  inline std::size_t get_vector_list(Sequence<std::string,Allocator>& vlist) const
17302  {
17303  if (!valid())
17304  return 0;
17305  else
17306  return local_data().vector_store.get_list(vlist);
17307  }
17308 
17309  inline bool symbol_exists(const std::string& symbol_name, const bool check_reserved_symb = true) const
17310  {
17311  /*
17312  Function will return true if symbol_name exists as either a
17313  reserved symbol, variable, stringvar, vector or function name
17314  in any of the type stores.
17315  */
17316  if (!valid())
17317  return false;
17318  else if (local_data().variable_store.symbol_exists(symbol_name))
17319  return true;
17320  #ifndef exprtk_disable_string_capabilities
17321  else if (local_data().stringvar_store.symbol_exists(symbol_name))
17322  return true;
17323  #endif
17324  else if (local_data().vector_store.symbol_exists(symbol_name))
17325  return true;
17326  else if (local_data().function_store.symbol_exists(symbol_name))
17327  return true;
17328  else if (check_reserved_symb && local_data().is_reserved_symbol(symbol_name))
17329  return true;
17330  else
17331  return false;
17332  }
17333 
17334  inline bool is_variable(const std::string& variable_name) const
17335  {
17336  if (!valid())
17337  return false;
17338  else
17339  return local_data().variable_store.symbol_exists(variable_name);
17340  }
17341 
17342  #ifndef exprtk_disable_string_capabilities
17343  inline bool is_stringvar(const std::string& stringvar_name) const
17344  {
17345  if (!valid())
17346  return false;
17347  else
17348  return local_data().stringvar_store.symbol_exists(stringvar_name);
17349  }
17350 
17351  inline bool is_conststr_stringvar(const std::string& symbol_name) const
17352  {
17353  if (!valid())
17354  return false;
17355  else if (!valid_symbol(symbol_name))
17356  return false;
17357  else if (!local_data().stringvar_store.symbol_exists(symbol_name))
17358  return false;
17359 
17360  return (
17361  local_data().stringvar_store.symbol_exists(symbol_name) ||
17362  local_data().stringvar_store.is_constant (symbol_name)
17363  );
17364  }
17365  #endif
17366 
17367  inline bool is_function(const std::string& function_name) const
17368  {
17369  if (!valid())
17370  return false;
17371  else
17372  return local_data().function_store.symbol_exists(function_name);
17373  }
17374 
17375  inline bool is_vararg_function(const std::string& vararg_function_name) const
17376  {
17377  if (!valid())
17378  return false;
17379  else
17380  return local_data().vararg_function_store.symbol_exists(vararg_function_name);
17381  }
17382 
17383  inline bool is_vector(const std::string& vector_name) const
17384  {
17385  if (!valid())
17386  return false;
17387  else
17388  return local_data().vector_store.symbol_exists(vector_name);
17389  }
17390 
17391  inline std::string get_variable_name(const expression_ptr& ptr) const
17392  {
17393  return local_data().variable_store.entity_name(ptr);
17394  }
17395 
17396  inline std::string get_vector_name(const vector_holder_ptr& ptr) const
17397  {
17398  return local_data().vector_store.entity_name(ptr);
17399  }
17400 
17401  #ifndef exprtk_disable_string_capabilities
17402  inline std::string get_stringvar_name(const expression_ptr& ptr) const
17403  {
17404  return local_data().stringvar_store.entity_name(ptr);
17405  }
17406 
17407  inline std::string get_conststr_stringvar_name(const expression_ptr& ptr) const
17408  {
17409  return local_data().stringvar_store.entity_name(ptr);
17410  }
17411  #endif
17412 
17413  inline bool valid() const
17414  {
17415  // Symbol table sanity check.
17416  return control_block_ && control_block_->data_;
17417  }
17418 
17419  inline void load_from(const symbol_table<T>& st)
17420  {
17421  {
17422  std::vector<std::string> name_list;
17423 
17424  st.local_data().function_store.get_list(name_list);
17425 
17426  if (!name_list.empty())
17427  {
17428  for (std::size_t i = 0; i < name_list.size(); ++i)
17429  {
17430  exprtk::ifunction<T>& ifunc = *st.get_function(name_list[i]);
17431  add_function(name_list[i],ifunc);
17432  }
17433  }
17434  }
17435 
17436  {
17437  std::vector<std::string> name_list;
17438 
17439  st.local_data().vararg_function_store.get_list(name_list);
17440 
17441  if (!name_list.empty())
17442  {
17443  for (std::size_t i = 0; i < name_list.size(); ++i)
17444  {
17445  exprtk::ivararg_function<T>& ivafunc = *st.get_vararg_function(name_list[i]);
17446  add_function(name_list[i],ivafunc);
17447  }
17448  }
17449  }
17450 
17451  {
17452  std::vector<std::string> name_list;
17453 
17454  st.local_data().generic_function_store.get_list(name_list);
17455 
17456  if (!name_list.empty())
17457  {
17458  for (std::size_t i = 0; i < name_list.size(); ++i)
17459  {
17460  exprtk::igeneric_function<T>& ifunc = *st.get_generic_function(name_list[i]);
17461  add_function(name_list[i],ifunc);
17462  }
17463  }
17464  }
17465 
17466  {
17467  std::vector<std::string> name_list;
17468 
17469  st.local_data().string_function_store.get_list(name_list);
17470 
17471  if (!name_list.empty())
17472  {
17473  for (std::size_t i = 0; i < name_list.size(); ++i)
17474  {
17475  exprtk::igeneric_function<T>& ifunc = *st.get_string_function(name_list[i]);
17476  add_function(name_list[i],ifunc);
17477  }
17478  }
17479  }
17480  }
17481 
17482  private:
17483 
17484  inline bool valid_symbol(const std::string& symbol, const bool check_reserved_symb = true) const
17485  {
17486  if (symbol.empty())
17487  return false;
17488  else if (!details::is_letter(symbol[0]))
17489  return false;
17490  else if (symbol.size() > 1)
17491  {
17492  for (std::size_t i = 1; i < symbol.size(); ++i)
17493  {
17494  if (
17495  !details::is_letter_or_digit(symbol[i]) &&
17496  ('_' != symbol[i])
17497  )
17498  {
17499  if (('.' == symbol[i]) && (i < (symbol.size() - 1)))
17500  continue;
17501  else
17502  return false;
17503  }
17504  }
17505  }
17506 
17507  return (check_reserved_symb) ? (!local_data().is_reserved_symbol(symbol)) : true;
17508  }
17509 
17510  inline bool valid_function(const std::string& symbol) const
17511  {
17512  if (symbol.empty())
17513  return false;
17514  else if (!details::is_letter(symbol[0]))
17515  return false;
17516  else if (symbol.size() > 1)
17517  {
17518  for (std::size_t i = 1; i < symbol.size(); ++i)
17519  {
17520  if (
17521  !details::is_letter_or_digit(symbol[i]) &&
17522  ('_' != symbol[i])
17523  )
17524  {
17525  if (('.' == symbol[i]) && (i < (symbol.size() - 1)))
17526  continue;
17527  else
17528  return false;
17529  }
17530  }
17531  }
17532 
17533  return true;
17534  }
17535 
17537 
17538  inline local_data_t& local_data()
17539  {
17540  return *(control_block_->data_);
17541  }
17542 
17543  inline const local_data_t& local_data() const
17544  {
17545  return *(control_block_->data_);
17546  }
17547 
17549 
17550  friend class parser<T>;
17551  };
17552 
17553  template <typename T>
17555 
17556  template <typename T>
17558  {
17559  private:
17560 
17563  typedef std::vector<symbol_table<T> > symtab_list_t;
17564 
17566  {
17568  {
17574  e_string
17575  };
17576 
17577  struct data_pack
17578  {
17580  : pointer(0),
17581  type(e_unknown),
17582  size(0)
17583  {}
17584 
17585  data_pack(void* ptr, const data_type dt, const std::size_t sz = 0)
17586  : pointer(ptr),
17587  type(dt),
17588  size(sz)
17589  {}
17590 
17591  void* pointer;
17593  std::size_t size;
17594  };
17595 
17596  typedef std::vector<data_pack> local_data_list_t;
17598 
17600  : ref_count(0),
17601  expr (0),
17602  results (0),
17603  retinv_null(false),
17604  return_invoked(&retinv_null)
17605  {}
17606 
17607  control_block(expression_ptr e)
17608  : ref_count(1),
17609  expr (e),
17610  results (0),
17611  retinv_null(false),
17612  return_invoked(&retinv_null)
17613  {}
17614 
17616  {
17617  if (expr && details::branch_deletable(expr))
17618  {
17619  destroy_node(expr);
17620  }
17621 
17622  if (!local_data_list.empty())
17623  {
17624  for (std::size_t i = 0; i < local_data_list.size(); ++i)
17625  {
17626  switch (local_data_list[i].type)
17627  {
17628  case e_expr : delete reinterpret_cast<expression_ptr>(local_data_list[i].pointer);
17629  break;
17630 
17631  case e_vecholder : delete reinterpret_cast<vector_holder_ptr>(local_data_list[i].pointer);
17632  break;
17633 
17634  case e_data : delete (T*)(local_data_list[i].pointer);
17635  break;
17636 
17637  case e_vecdata : delete [] (T*)(local_data_list[i].pointer);
17638  break;
17639 
17640  case e_string : delete (std::string*)(local_data_list[i].pointer);
17641  break;
17642 
17643  default : break;
17644  }
17645  }
17646  }
17647 
17648  if (results)
17649  {
17650  delete results;
17651  }
17652  }
17653 
17654  static inline control_block* create(expression_ptr e)
17655  {
17656  return new control_block(e);
17657  }
17658 
17659  static inline void destroy(control_block*& cntrl_blck)
17660  {
17661  if (cntrl_blck)
17662  {
17663  if (
17664  (0 != cntrl_blck->ref_count) &&
17665  (0 == --cntrl_blck->ref_count)
17666  )
17667  {
17668  delete cntrl_blck;
17669  }
17670 
17671  cntrl_blck = 0;
17672  }
17673  }
17674 
17675  std::size_t ref_count;
17676  expression_ptr expr;
17681 
17682  friend class function_compositor<T>;
17683  };
17684 
17685  public:
17686 
17688  : control_block_(0)
17689  {
17690  set_expression(new details::null_node<T>());
17691  }
17692 
17694  : control_block_ (e.control_block_ ),
17695  symbol_table_list_(e.symbol_table_list_)
17696  {
17697  control_block_->ref_count++;
17698  }
17699 
17700  expression(const symbol_table<T>& symbol_table)
17701  : control_block_(0)
17702  {
17703  set_expression(new details::null_node<T>());
17704  symbol_table_list_.push_back(symbol_table);
17705  }
17706 
17708  {
17709  if (this != &e)
17710  {
17711  if (control_block_)
17712  {
17713  if (
17714  (0 != control_block_->ref_count) &&
17715  (0 == --control_block_->ref_count)
17716  )
17717  {
17718  delete control_block_;
17719  }
17720 
17721  control_block_ = 0;
17722  }
17723 
17724  control_block_ = e.control_block_;
17725  control_block_->ref_count++;
17726  symbol_table_list_ = e.symbol_table_list_;
17727  }
17728 
17729  return *this;
17730  }
17731 
17732  inline bool operator==(const expression<T>& e)
17733  {
17734  return (this == &e);
17735  }
17736 
17737  inline bool operator!() const
17738  {
17739  return (
17740  (0 == control_block_ ) ||
17741  (0 == control_block_->expr)
17742  );
17743  }
17744 
17746  {
17747  control_block::destroy(control_block_);
17748 
17749  return (*this);
17750  }
17751 
17753  {
17754  control_block::destroy(control_block_);
17755  }
17756 
17757  inline T value() const
17758  {
17759  return control_block_->expr->value();
17760  }
17761 
17762  inline T operator() () const
17763  {
17764  return value();
17765  }
17766 
17767  inline operator T() const
17768  {
17769  return value();
17770  }
17771 
17772  inline operator bool() const
17773  {
17774  return details::is_true(value());
17775  }
17776 
17778  {
17779  symbol_table_list_.push_back(st);
17780  }
17781 
17782  inline const symbol_table<T>& get_symbol_table(const std::size_t& index = 0) const
17783  {
17784  return symbol_table_list_[index];
17785  }
17786 
17787  inline symbol_table<T>& get_symbol_table(const std::size_t& index = 0)
17788  {
17789  return symbol_table_list_[index];
17790  }
17791 
17793 
17794  inline const results_context_t& results() const
17795  {
17796  if (control_block_->results)
17797  return (*control_block_->results);
17798  else
17799  {
17800  static const results_context_t null_results;
17801  return null_results;
17802  }
17803  }
17804 
17805  inline bool return_invoked() const
17806  {
17807  return (*control_block_->return_invoked);
17808  }
17809 
17810  private:
17811 
17813  {
17814  return symbol_table_list_;
17815  }
17816 
17817  inline void set_expression(const expression_ptr expr)
17818  {
17819  if (expr)
17820  {
17821  if (control_block_)
17822  {
17823  if (0 == --control_block_->ref_count)
17824  {
17825  delete control_block_;
17826  }
17827  }
17828 
17829  control_block_ = control_block::create(expr);
17830  }
17831  }
17832 
17833  inline void register_local_var(expression_ptr expr)
17834  {
17835  if (expr)
17836  {
17837  if (control_block_)
17838  {
17839  control_block_->
17840  local_data_list.push_back(
17841  typename expression<T>::control_block::
17842  data_pack(reinterpret_cast<void*>(expr),
17843  control_block::e_expr));
17844  }
17845  }
17846  }
17847 
17848  inline void register_local_var(vector_holder_ptr vec_holder)
17849  {
17850  if (vec_holder)
17851  {
17852  if (control_block_)
17853  {
17854  control_block_->
17855  local_data_list.push_back(
17856  typename expression<T>::control_block::
17857  data_pack(reinterpret_cast<void*>(vec_holder),
17858  control_block::e_vecholder));
17859  }
17860  }
17861  }
17862 
17863  inline void register_local_data(void* data, const std::size_t& size = 0, const std::size_t data_mode = 0)
17864  {
17865  if (data)
17866  {
17867  if (control_block_)
17868  {
17869  typename control_block::data_type dt = control_block::e_data;
17870 
17871  switch (data_mode)
17872  {
17873  case 0 : dt = control_block::e_data; break;
17874  case 1 : dt = control_block::e_vecdata; break;
17875  case 2 : dt = control_block::e_string; break;
17876  }
17877 
17878  control_block_->
17879  local_data_list.push_back(
17880  typename expression<T>::control_block::
17881  data_pack(reinterpret_cast<void*>(data), dt, size));
17882  }
17883  }
17884  }
17885 
17887  {
17888  if (control_block_)
17889  {
17890  return control_block_->local_data_list;
17891  }
17892  else
17893  {
17894  static typename control_block::local_data_list_t null_local_data_list;
17895  return null_local_data_list;
17896  }
17897  }
17898 
17900  {
17901  if (control_block_ && rc)
17902  {
17903  control_block_->results = rc;
17904  }
17905  }
17906 
17907  inline void set_retinvk(bool* retinvk_ptr)
17908  {
17909  if (control_block_)
17910  {
17911  control_block_->return_invoked = retinvk_ptr;
17912  }
17913  }
17914 
17917 
17918  friend class parser<T>;
17919  friend class expression_helper<T>;
17920  friend class function_compositor<T>;
17921  };
17922 
17923  template <typename T>
17924  class expression_helper
17925  {
17926  public:
17927 
17928  static inline bool is_constant(const expression<T>& expr)
17929  {
17930  return details::is_constant_node(expr.control_block_->expr);
17931  }
17932 
17933  static inline bool is_variable(const expression<T>& expr)
17934  {
17935  return details::is_variable_node(expr.control_block_->expr);
17936  }
17937 
17938  static inline bool is_unary(const expression<T>& expr)
17939  {
17940  return details::is_unary_node(expr.control_block_->expr);
17941  }
17942 
17943  static inline bool is_binary(const expression<T>& expr)
17944  {
17945  return details::is_binary_node(expr.control_block_->expr);
17946  }
17947 
17948  static inline bool is_function(const expression<T>& expr)
17949  {
17950  return details::is_function(expr.control_block_->expr);
17951  }
17952 
17953  static inline bool is_null(const expression<T>& expr)
17954  {
17955  return details::is_null_node(expr.control_block_->expr);
17956  }
17957  };
17958 
17959  template <typename T>
17960  inline bool is_valid(const expression<T>& expr)
17961  {
17962  return !expression_helper<T>::is_null(expr);
17963  }
17964 
17965  namespace parser_error
17966  {
17968  {
17971  e_token = 2,
17974  e_lexer = 6,
17976  };
17977 
17978  struct type
17979  {
17981  : mode(parser_error::e_unknown),
17982  line_no (0),
17983  column_no(0)
17984  {}
17985 
17988  std::string diagnostic;
17989  std::string src_location;
17990  std::string error_line;
17991  std::size_t line_no;
17992  std::size_t column_no;
17993  };
17994 
17995  inline type make_error(const error_mode mode,
17996  const std::string& diagnostic = "",
17997  const std::string& src_location = "")
17998  {
17999  type t;
18000  t.mode = mode;
18002  t.diagnostic = diagnostic;
18003  t.src_location = src_location;
18004  exprtk_debug(("%s\n",diagnostic .c_str()));
18005  return t;
18006  }
18007 
18008  inline type make_error(const error_mode mode,
18009  const lexer::token& tk,
18010  const std::string& diagnostic = "",
18011  const std::string& src_location = "")
18012  {
18013  type t;
18014  t.mode = mode;
18015  t.token = tk;
18016  t.diagnostic = diagnostic;
18017  t.src_location = src_location;
18018  exprtk_debug(("%s\n",diagnostic .c_str()));
18019  return t;
18020  }
18021 
18022  inline std::string to_str(error_mode mode)
18023  {
18024  switch (mode)
18025  {
18026  case e_unknown : return std::string("Unknown Error");
18027  case e_syntax : return std::string("Syntax Error" );
18028  case e_token : return std::string("Token Error" );
18029  case e_numeric : return std::string("Numeric Error");
18030  case e_symtab : return std::string("Symbol Error" );
18031  case e_lexer : return std::string("Lexer Error" );
18032  case e_helper : return std::string("Helper Error" );
18033  default : return std::string("Unknown Error");
18034  }
18035  }
18036 
18037  inline bool update_error(type& error, const std::string& expression)
18038  {
18039  if (
18040  expression.empty() ||
18041  (error.token.position > expression.size()) ||
18043  )
18044  {
18045  return false;
18046  }
18047 
18048  std::size_t error_line_start = 0;
18049 
18050  for (std::size_t i = error.token.position; i > 0; --i)
18051  {
18052  const details::char_t c = expression[i];
18053 
18054  if (('\n' == c) || ('\r' == c))
18055  {
18056  error_line_start = i + 1;
18057  break;
18058  }
18059  }
18060 
18061  std::size_t next_nl_position = std::min(expression.size(),
18062  expression.find_first_of('\n',error.token.position + 1));
18063 
18064  error.column_no = error.token.position - error_line_start;
18065  error.error_line = expression.substr(error_line_start,
18066  next_nl_position - error_line_start);
18067 
18068  error.line_no = 0;
18069 
18070  for (std::size_t i = 0; i < next_nl_position; ++i)
18071  {
18072  if ('\n' == expression[i])
18073  ++error.line_no;
18074  }
18075 
18076  return true;
18077  }
18078 
18079  inline void dump_error(const type& error)
18080  {
18081  printf("Position: %02d Type: [%s] Msg: %s\n",
18082  static_cast<int>(error.token.position),
18083  exprtk::parser_error::to_str(error.mode).c_str(),
18084  error.diagnostic.c_str());
18085  }
18086  }
18087 
18088  namespace details
18089  {
18090  template <typename Parser>
18091  inline void disable_type_checking(Parser& p)
18092  {
18093  p.state_.type_check_enabled = false;
18094  }
18095  }
18096 
18097  template <typename T>
18098  class parser : public lexer::parser_helper
18099  {
18100  private:
18101 
18103  {
18118  e_level14
18119  };
18120 
18121  typedef const T& cref_t;
18122  typedef const T const_t;
18123  typedef ifunction <T> F;
18140  #ifndef exprtk_disable_break_continue
18144  #endif
18152  #ifndef exprtk_disable_string_capabilities
18163  #endif
18178 
18180  typedef typename functor_t::qfunc_t quaternary_functor_t;
18181  typedef typename functor_t::tfunc_t trinary_functor_t;
18182  typedef typename functor_t::bfunc_t binary_functor_t;
18183  typedef typename functor_t::ufunc_t unary_functor_t;
18184 
18186 
18187  typedef std::map<operator_t, unary_functor_t> unary_op_map_t;
18188  typedef std::map<operator_t, binary_functor_t> binary_op_map_t;
18189  typedef std::map<operator_t,trinary_functor_t> trinary_op_map_t;
18190 
18191  typedef std::map<std::string,std::pair<trinary_functor_t ,operator_t> > sf3_map_t;
18192  typedef std::map<std::string,std::pair<quaternary_functor_t,operator_t> > sf4_map_t;
18193 
18194  typedef std::map<binary_functor_t,operator_t> inv_binary_op_map_t;
18195  typedef std::multimap<std::string,details::base_operation_t,details::ilesscompare> base_ops_map_t;
18196  typedef std::set<std::string,details::ilesscompare> disabled_func_set_t;
18197 
18201 
18209 
18215 
18220 
18222 
18223  typedef parser_helper prsrhlpr_t;
18224 
18226  {
18228  {
18233  e_string
18234  };
18235 
18238  typedef vector_holder_t* vector_holder_ptr;
18240  #ifndef exprtk_disable_string_capabilities
18242  #endif
18243 
18245  : name("???"),
18246  size (std::numeric_limits<std::size_t>::max()),
18247  index(std::numeric_limits<std::size_t>::max()),
18248  depth(std::numeric_limits<std::size_t>::max()),
18249  ref_count(0),
18250  ip_index (0),
18251  type (e_none),
18252  active(false),
18253  data (0),
18254  var_node(0),
18255  vec_node(0)
18256  #ifndef exprtk_disable_string_capabilities
18257  ,str_node(0)
18258  #endif
18259  {}
18260 
18261  bool operator < (const scope_element& se) const
18262  {
18263  if (ip_index < se.ip_index)
18264  return true;
18265  else if (ip_index > se.ip_index)
18266  return false;
18267  else if (depth < se.depth)
18268  return true;
18269  else if (depth > se.depth)
18270  return false;
18271  else if (index < se.index)
18272  return true;
18273  else if (index > se.index)
18274  return false;
18275  else
18276  return (name < se.name);
18277  }
18278 
18279  void clear()
18280  {
18281  name = "???";
18285  type = e_none;
18286  active = false;
18287  ref_count = 0;
18288  ip_index = 0;
18289  data = 0;
18290  var_node = 0;
18291  vec_node = 0;
18292  #ifndef exprtk_disable_string_capabilities
18293  str_node = 0;
18294  #endif
18295  }
18296 
18297  std::string name;
18298  std::size_t size;
18299  std::size_t index;
18300  std::size_t depth;
18301  std::size_t ref_count;
18302  std::size_t ip_index;
18304  bool active;
18305  void* data;
18307  vector_holder_ptr vec_node;
18308  #ifndef exprtk_disable_string_capabilities
18310  #endif
18311  };
18312 
18314  {
18315  public:
18316 
18320 
18322  : parser_(p),
18323  input_param_cnt_(0)
18324  {}
18325 
18326  inline std::size_t size() const
18327  {
18328  return element_.size();
18329  }
18330 
18331  inline bool empty() const
18332  {
18333  return element_.empty();
18334  }
18335 
18336  inline scope_element& get_element(const std::size_t& index)
18337  {
18338  if (index < element_.size())
18339  return element_[index];
18340  else
18341  return null_element_;
18342  }
18343 
18344  inline scope_element& get_element(const std::string& var_name,
18345  const std::size_t index = std::numeric_limits<std::size_t>::max())
18346  {
18347  const std::size_t current_depth = parser_.state_.scope_depth;
18348 
18349  for (std::size_t i = 0; i < element_.size(); ++i)
18350  {
18351  scope_element& se = element_[i];
18352 
18353  if (se.depth > current_depth)
18354  continue;
18355  else if (
18356  details::imatch(se.name, var_name) &&
18357  (se.index == index)
18358  )
18359  return se;
18360  }
18361 
18362  return null_element_;
18363  }
18364 
18365  inline scope_element& get_active_element(const std::string& var_name,
18366  const std::size_t index = std::numeric_limits<std::size_t>::max())
18367  {
18368  const std::size_t current_depth = parser_.state_.scope_depth;
18369 
18370  for (std::size_t i = 0; i < element_.size(); ++i)
18371  {
18372  scope_element& se = element_[i];
18373 
18374  if (se.depth > current_depth)
18375  continue;
18376  else if (
18377  details::imatch(se.name, var_name) &&
18378  (se.index == index) &&
18379  (se.active)
18380  )
18381  return se;
18382  }
18383 
18384  return null_element_;
18385  }
18386 
18387  inline bool add_element(const scope_element& se)
18388  {
18389  for (std::size_t i = 0; i < element_.size(); ++i)
18390  {
18391  scope_element& cse = element_[i];
18392 
18393  if (
18394  details::imatch(cse.name, se.name) &&
18395  (cse.depth <= se.depth) &&
18396  (cse.index == se.index) &&
18397  (cse.size == se.size ) &&
18398  (cse.type == se.type ) &&
18399  (cse.active)
18400  )
18401  return false;
18402  }
18403 
18404  element_.push_back(se);
18405  std::sort(element_.begin(),element_.end());
18406 
18407  return true;
18408  }
18409 
18410  inline void deactivate(const std::size_t& scope_depth)
18411  {
18412  exprtk_debug(("deactivate() - Scope depth: %d\n",
18413  static_cast<int>(parser_.state_.scope_depth)));
18414 
18415  for (std::size_t i = 0; i < element_.size(); ++i)
18416  {
18417  scope_element& se = element_[i];
18418 
18419  if (se.active && (se.depth >= scope_depth))
18420  {
18421  exprtk_debug(("deactivate() - element[%02d] '%s'\n",
18422  static_cast<int>(i),
18423  se.name.c_str()));
18424 
18425  se.active = false;
18426  }
18427  }
18428  }
18429 
18430  inline void free_element(scope_element& se)
18431  {
18432  switch (se.type)
18433  {
18434  case scope_element::e_variable : if (se.data ) delete (T*) se.data;
18435  if (se.var_node) delete se.var_node;
18436  break;
18437 
18438  case scope_element::e_vector : if (se.data ) delete[] (T*) se.data;
18439  if (se.vec_node) delete se.vec_node;
18440  break;
18441 
18442  case scope_element::e_vecelem : if (se.var_node) delete se.var_node;
18443  break;
18444 
18445  #ifndef exprtk_disable_string_capabilities
18446  case scope_element::e_string : if (se.data ) delete (std::string*) se.data;
18447  if (se.str_node) delete se.str_node;
18448  break;
18449  #endif
18450 
18451  default : return;
18452  }
18453 
18454  se.clear();
18455  }
18456 
18457  inline void cleanup()
18458  {
18459  for (std::size_t i = 0; i < element_.size(); ++i)
18460  {
18461  free_element(element_[i]);
18462  }
18463 
18464  element_.clear();
18465 
18466  input_param_cnt_ = 0;
18467  }
18468 
18469  inline std::size_t next_ip_index()
18470  {
18471  return ++input_param_cnt_;
18472  }
18473 
18475  {
18476  for (std::size_t i = 0; i < element_.size(); ++i)
18477  {
18478  scope_element& se = element_[i];
18479 
18480  if (
18481  se.active &&
18482  se.var_node &&
18484  )
18485  {
18486  variable_node_ptr vn = reinterpret_cast<variable_node_ptr>(se.var_node);
18487 
18488  if (&(vn->ref()) == (&v))
18489  {
18490  return se.var_node;
18491  }
18492  }
18493  }
18494 
18495  return expression_node_ptr(0);
18496  }
18497 
18498  private:
18499 
18500  scope_element_manager& operator=(const scope_element_manager&);
18501 
18503  std::vector<scope_element> element_;
18505  std::size_t input_param_cnt_;
18506  };
18507 
18509  {
18510  public:
18511 
18513 
18515  : parser_(p)
18516  {
18517  parser_.state_.scope_depth++;
18518  #ifdef exprtk_enable_debugging
18519  std::string depth(2 * parser_.state_.scope_depth,'-');
18520  exprtk_debug(("%s> Scope Depth: %02d\n",
18521  depth.c_str(),
18522  static_cast<int>(parser_.state_.scope_depth)));
18523  #endif
18524  }
18525 
18527  {
18528  parser_.sem_.deactivate(parser_.state_.scope_depth);
18529  parser_.state_.scope_depth--;
18530  #ifdef exprtk_enable_debugging
18531  std::string depth(2 * parser_.state_.scope_depth,'-');
18532  exprtk_debug(("<%s Scope Depth: %02d\n",
18533  depth.c_str(),
18534  static_cast<int>(parser_.state_.scope_depth)));
18535  #endif
18536  }
18537 
18538  private:
18539 
18540  scope_handler& operator=(const scope_handler&);
18541 
18543  };
18544 
18546  {
18548 
18552  #ifndef exprtk_disable_string_capabilities
18554  #endif
18558 
18559  inline bool empty() const
18560  {
18561  return symtab_list_.empty();
18562  }
18563 
18564  inline void clear()
18565  {
18566  symtab_list_.clear();
18567  }
18568 
18569  inline bool valid() const
18570  {
18571  if (!empty())
18572  {
18573  for (std::size_t i = 0; i < symtab_list_.size(); ++i)
18574  {
18575  if (symtab_list_[i].valid())
18576  return true;
18577  }
18578  }
18579 
18580  return false;
18581  }
18582 
18583  inline bool valid_symbol(const std::string& symbol) const
18584  {
18585  if (!symtab_list_.empty())
18586  return symtab_list_[0].valid_symbol(symbol);
18587  else
18588  return false;
18589  }
18590 
18591  inline bool valid_function_name(const std::string& symbol) const
18592  {
18593  if (!symtab_list_.empty())
18594  return symtab_list_[0].valid_function(symbol);
18595  else
18596  return false;
18597  }
18598 
18599  inline variable_ptr get_variable(const std::string& variable_name) const
18600  {
18601  if (!valid_symbol(variable_name))
18602  return reinterpret_cast<variable_ptr>(0);
18603 
18604  variable_ptr result = reinterpret_cast<variable_ptr>(0);
18605 
18606  for (std::size_t i = 0; i < symtab_list_.size(); ++i)
18607  {
18608  if (!symtab_list_[i].valid())
18609  continue;
18610  else
18611  result = local_data(i)
18612  .variable_store.get(variable_name);
18613 
18614  if (result) break;
18615  }
18616 
18617  return result;
18618  }
18619 
18620  inline variable_ptr get_variable(const T& var_ref) const
18621  {
18622  variable_ptr result = reinterpret_cast<variable_ptr>(0);
18623 
18624  for (std::size_t i = 0; i < symtab_list_.size(); ++i)
18625  {
18626  if (!symtab_list_[i].valid())
18627  continue;
18628  else
18629  result = local_data(i).variable_store
18630  .get_from_varptr(reinterpret_cast<const void*>(&var_ref));
18631 
18632  if (result) break;
18633  }
18634 
18635  return result;
18636  }
18637 
18638  #ifndef exprtk_disable_string_capabilities
18639  inline stringvar_ptr get_stringvar(const std::string& string_name) const
18640  {
18641  if (!valid_symbol(string_name))
18642  return reinterpret_cast<stringvar_ptr>(0);
18643 
18644  stringvar_ptr result = reinterpret_cast<stringvar_ptr>(0);
18645 
18646  for (std::size_t i = 0; i < symtab_list_.size(); ++i)
18647  {
18648  if (!symtab_list_[i].valid())
18649  continue;
18650  else
18651  result = local_data(i)
18652  .stringvar_store.get(string_name);
18653 
18654  if (result) break;
18655  }
18656 
18657  return result;
18658  }
18659  #endif
18660 
18661  inline function_ptr get_function(const std::string& function_name) const
18662  {
18663  if (!valid_function_name(function_name))
18664  return reinterpret_cast<function_ptr>(0);
18665 
18666  function_ptr result = reinterpret_cast<function_ptr>(0);
18667 
18668  for (std::size_t i = 0; i < symtab_list_.size(); ++i)
18669  {
18670  if (!symtab_list_[i].valid())
18671  continue;
18672  else
18673  result = local_data(i)
18674  .function_store.get(function_name);
18675 
18676  if (result) break;
18677  }
18678 
18679  return result;
18680  }
18681 
18682  inline vararg_function_ptr get_vararg_function(const std::string& vararg_function_name) const
18683  {
18684  if (!valid_function_name(vararg_function_name))
18685  return reinterpret_cast<vararg_function_ptr>(0);
18686 
18687  vararg_function_ptr result = reinterpret_cast<vararg_function_ptr>(0);
18688 
18689  for (std::size_t i = 0; i < symtab_list_.size(); ++i)
18690  {
18691  if (!symtab_list_[i].valid())
18692  continue;
18693  else
18694  result = local_data(i)
18695  .vararg_function_store.get(vararg_function_name);
18696 
18697  if (result) break;
18698  }
18699 
18700  return result;
18701  }
18702 
18703  inline generic_function_ptr get_generic_function(const std::string& function_name) const
18704  {
18705  if (!valid_function_name(function_name))
18706  return reinterpret_cast<generic_function_ptr>(0);
18707 
18708  generic_function_ptr result = reinterpret_cast<generic_function_ptr>(0);
18709 
18710  for (std::size_t i = 0; i < symtab_list_.size(); ++i)
18711  {
18712  if (!symtab_list_[i].valid())
18713  continue;
18714  else
18715  result = local_data(i)
18716  .generic_function_store.get(function_name);
18717 
18718  if (result) break;
18719  }
18720 
18721  return result;
18722  }
18723 
18724  inline generic_function_ptr get_string_function(const std::string& function_name) const
18725  {
18726  if (!valid_function_name(function_name))
18727  return reinterpret_cast<generic_function_ptr>(0);
18728 
18729  generic_function_ptr result = reinterpret_cast<generic_function_ptr>(0);
18730 
18731  for (std::size_t i = 0; i < symtab_list_.size(); ++i)
18732  {
18733  if (!symtab_list_[i].valid())
18734  continue;
18735  else
18736  result =
18737  local_data(i).string_function_store.get(function_name);
18738 
18739  if (result) break;
18740  }
18741 
18742  return result;
18743  }
18744 
18745  inline vector_holder_ptr get_vector(const std::string& vector_name) const
18746  {
18747  if (!valid_symbol(vector_name))
18748  return reinterpret_cast<vector_holder_ptr>(0);
18749 
18750  vector_holder_ptr result = reinterpret_cast<vector_holder_ptr>(0);
18751 
18752  for (std::size_t i = 0; i < symtab_list_.size(); ++i)
18753  {
18754  if (!symtab_list_[i].valid())
18755  continue;
18756  else
18757  result =
18758  local_data(i).vector_store.get(vector_name);
18759 
18760  if (result) break;
18761  }
18762 
18763  return result;
18764  }
18765 
18766  inline bool is_constant_node(const std::string& symbol_name) const
18767  {
18768  if (!valid_symbol(symbol_name))
18769  return false;
18770 
18771  for (std::size_t i = 0; i < symtab_list_.size(); ++i)
18772  {
18773  if (!symtab_list_[i].valid())
18774  continue;
18775  else if (local_data(i).variable_store.is_constant(symbol_name))
18776  return true;
18777  }
18778 
18779  return false;
18780  }
18781 
18782  #ifndef exprtk_disable_string_capabilities
18783  inline bool is_constant_string(const std::string& symbol_name) const
18784  {
18785  if (!valid_symbol(symbol_name))
18786  return false;
18787 
18788  for (std::size_t i = 0; i < symtab_list_.size(); ++i)
18789  {
18790  if (!symtab_list_[i].valid())
18791  continue;
18792  else if (!local_data(i).stringvar_store.symbol_exists(symbol_name))
18793  continue;
18794  else if ( local_data(i).stringvar_store.is_constant(symbol_name))
18795  return true;
18796  }
18797 
18798  return false;
18799  }
18800  #endif
18801 
18802  inline bool symbol_exists(const std::string& symbol) const
18803  {
18804  for (std::size_t i = 0; i < symtab_list_.size(); ++i)
18805  {
18806  if (!symtab_list_[i].valid())
18807  continue;
18808  else if (symtab_list_[i].symbol_exists(symbol))
18809  return true;
18810  }
18811 
18812  return false;
18813  }
18814 
18815  inline bool is_variable(const std::string& variable_name) const
18816  {
18817  for (std::size_t i = 0; i < symtab_list_.size(); ++i)
18818  {
18819  if (!symtab_list_[i].valid())
18820  continue;
18821  else if (
18822  symtab_list_[i].local_data().variable_store
18823  .symbol_exists(variable_name)
18824  )
18825  return true;
18826  }
18827 
18828  return false;
18829  }
18830 
18831  #ifndef exprtk_disable_string_capabilities
18832  inline bool is_stringvar(const std::string& stringvar_name) const
18833  {
18834  for (std::size_t i = 0; i < symtab_list_.size(); ++i)
18835  {
18836  if (!symtab_list_[i].valid())
18837  continue;
18838  else if (
18839  symtab_list_[i].local_data().stringvar_store
18840  .symbol_exists(stringvar_name)
18841  )
18842  return true;
18843  }
18844 
18845  return false;
18846  }
18847 
18848  inline bool is_conststr_stringvar(const std::string& symbol_name) const
18849  {
18850  for (std::size_t i = 0; i < symtab_list_.size(); ++i)
18851  {
18852  if (!symtab_list_[i].valid())
18853  continue;
18854  else if (
18855  symtab_list_[i].local_data().stringvar_store
18856  .symbol_exists(symbol_name)
18857  )
18858  {
18859  return (
18860  local_data(i).stringvar_store.symbol_exists(symbol_name) ||
18861  local_data(i).stringvar_store.is_constant (symbol_name)
18862  );
18863 
18864  }
18865  }
18866 
18867  return false;
18868  }
18869  #endif
18870 
18871  inline bool is_function(const std::string& function_name) const
18872  {
18873  for (std::size_t i = 0; i < symtab_list_.size(); ++i)
18874  {
18875  if (!symtab_list_[i].valid())
18876  continue;
18877  else if (
18878  local_data(i).vararg_function_store
18879  .symbol_exists(function_name)
18880  )
18881  return true;
18882  }
18883 
18884  return false;
18885  }
18886 
18887  inline bool is_vararg_function(const std::string& vararg_function_name) const
18888  {
18889  for (std::size_t i = 0; i < symtab_list_.size(); ++i)
18890  {
18891  if (!symtab_list_[i].valid())
18892  continue;
18893  else if (
18894  local_data(i).vararg_function_store
18895  .symbol_exists(vararg_function_name)
18896  )
18897  return true;
18898  }
18899 
18900  return false;
18901  }
18902 
18903  inline bool is_vector(const std::string& vector_name) const
18904  {
18905  for (std::size_t i = 0; i < symtab_list_.size(); ++i)
18906  {
18907  if (!symtab_list_[i].valid())
18908  continue;
18909  else if (
18910  local_data(i).vector_store
18911  .symbol_exists(vector_name)
18912  )
18913  return true;
18914  }
18915 
18916  return false;
18917  }
18918 
18919  inline std::string get_variable_name(const expression_node_ptr& ptr) const
18920  {
18921  return local_data().variable_store.entity_name(ptr);
18922  }
18923 
18924  inline std::string get_vector_name(const vector_holder_ptr& ptr) const
18925  {
18926  return local_data().vector_store.entity_name(ptr);
18927  }
18928 
18929  #ifndef exprtk_disable_string_capabilities
18930  inline std::string get_stringvar_name(const expression_node_ptr& ptr) const
18931  {
18932  return local_data().stringvar_store.entity_name(ptr);
18933  }
18934 
18935  inline std::string get_conststr_stringvar_name(const expression_node_ptr& ptr) const
18936  {
18937  return local_data().stringvar_store.entity_name(ptr);
18938  }
18939  #endif
18940 
18941  inline local_data_t& local_data(const std::size_t& index = 0)
18942  {
18943  return symtab_list_[index].local_data();
18944  }
18945 
18946  inline const local_data_t& local_data(const std::size_t& index = 0) const
18947  {
18948  return symtab_list_[index].local_data();
18949  }
18950 
18951  inline symbol_table_t& get_symbol_table(const std::size_t& index = 0)
18952  {
18953  return symtab_list_[index];
18954  }
18955  };
18956 
18958  {
18960  : type_check_enabled(true)
18961  {
18962  reset();
18963  }
18964 
18965  void reset()
18966  {
18967  parsing_return_stmt = false;
18968  parsing_break_stmt = false;
18969  return_stmt_present = false;
18970  side_effect_present = false;
18971  scope_depth = 0;
18972  }
18973 
18974  #ifndef exprtk_enable_debugging
18975  void activate_side_effect(const std::string&)
18976  #else
18977  void activate_side_effect(const std::string& source)
18978  #endif
18979  {
18980  if (!side_effect_present)
18981  {
18982  side_effect_present = true;
18983 
18984  exprtk_debug(("activate_side_effect() - caller: %s\n",source.c_str()));
18985  }
18986  }
18987 
18993  std::size_t scope_depth;
18994  };
18995 
18996  public:
18997 
18999  {
19000 
19002  {
19003  e_usr_variable_type = 0,
19004  e_usr_constant_type = 1
19005  };
19006 
19008  {
19009  e_usrmode_default = 0,
19010  e_usrmode_extended = 1
19011  };
19012 
19014 
19015  unknown_symbol_resolver(const usr_mode m = e_usrmode_default)
19016  : mode(m)
19017  {}
19018 
19020  {}
19021 
19022  virtual bool process(const std::string& /*unknown_symbol*/,
19023  usr_symbol_type& st,
19024  T& default_value,
19025  std::string& error_message)
19026  {
19027  if (e_usrmode_default != mode)
19028  return false;
19029 
19030  st = e_usr_variable_type;
19031  default_value = T(0);
19032  error_message.clear();
19033 
19034  return true;
19035  }
19036 
19037  virtual bool process(const std::string& /* unknown_symbol */,
19038  symbol_table_t& /* symbol_table */,
19039  std::string& /* error_message */)
19040  {
19041  return false;
19042  }
19043  };
19044 
19046  {
19047  e_ct_none = 0,
19048  e_ct_variables = 1,
19049  e_ct_functions = 2,
19050  e_ct_assignments = 4
19051  };
19052 
19054  {
19055  e_st_unknown = 0,
19056  e_st_variable = 1,
19057  e_st_vector = 2,
19058  e_st_vecelem = 3,
19059  e_st_string = 4,
19060  e_st_function = 5,
19061  e_st_local_variable = 6,
19062  e_st_local_vector = 7,
19063  e_st_local_string = 8
19064  };
19065 
19067  {
19068  public:
19069 
19070  typedef std::pair<std::string,symbol_type> symbol_t;
19071  typedef std::vector<symbol_t> symbol_list_t;
19072 
19073  dependent_entity_collector(const std::size_t options = e_ct_none)
19074  : options_(options),
19075  collect_variables_ ((options_ & e_ct_variables ) == e_ct_variables ),
19076  collect_functions_ ((options_ & e_ct_functions ) == e_ct_functions ),
19077  collect_assignments_((options_ & e_ct_assignments) == e_ct_assignments),
19078  return_present_ (false),
19079  final_stmt_return_(false)
19080  {}
19081 
19082  template <typename Allocator,
19083  template <typename,typename> class Sequence>
19084  inline std::size_t symbols(Sequence<symbol_t,Allocator>& symbols_list)
19085  {
19086  if (!collect_variables_ && !collect_functions_)
19087  return 0;
19088  else if (symbol_name_list_.empty())
19089  return 0;
19090 
19091  for (std::size_t i = 0; i < symbol_name_list_.size(); ++i)
19092  {
19093  details::case_normalise(symbol_name_list_[i].first);
19094  }
19095 
19096  std::sort(symbol_name_list_.begin(),symbol_name_list_.end());
19097 
19098  std::unique_copy(symbol_name_list_.begin(),
19099  symbol_name_list_.end (),
19100  std::back_inserter(symbols_list));
19101 
19102  return symbols_list.size();
19103  }
19104 
19105  template <typename Allocator,
19106  template <typename,typename> class Sequence>
19107  inline std::size_t assignment_symbols(Sequence<symbol_t,Allocator>& assignment_list)
19108  {
19109  if (!collect_assignments_)
19110  return 0;
19111  else if (assignment_name_list_.empty())
19112  return 0;
19113 
19114  for (std::size_t i = 0; i < assignment_name_list_.size(); ++i)
19115  {
19116  details::case_normalise(assignment_name_list_[i].first);
19117  }
19118 
19119  std::sort(assignment_name_list_.begin(),assignment_name_list_.end());
19120 
19121  std::unique_copy(assignment_name_list_.begin(),
19122  assignment_name_list_.end (),
19123  std::back_inserter(assignment_list));
19124 
19125  return assignment_list.size();
19126  }
19127 
19128  void clear()
19129  {
19130  symbol_name_list_ .clear();
19131  assignment_name_list_.clear();
19132  retparam_list_ .clear();
19133  return_present_ = false;
19134  final_stmt_return_ = false;
19135  }
19136 
19138  {
19139  return collect_variables_;
19140  }
19141 
19143  {
19144  return collect_functions_;
19145  }
19146 
19148  {
19149  return collect_assignments_;
19150  }
19151 
19152  bool return_present() const
19153  {
19154  return return_present_;
19155  }
19156 
19157  bool final_stmt_return() const
19158  {
19159  return final_stmt_return_;
19160  }
19161 
19162  typedef std::vector<std::string> retparam_list_t;
19163 
19165  {
19166  return retparam_list_;
19167  }
19168 
19169  private:
19170 
19171  inline void add_symbol(const std::string& symbol, const symbol_type st)
19172  {
19173  switch (st)
19174  {
19175  case e_st_variable :
19176  case e_st_vector :
19177  case e_st_string :
19178  case e_st_local_variable :
19179  case e_st_local_vector :
19180  case e_st_local_string : if (collect_variables_)
19181  symbol_name_list_
19182  .push_back(std::make_pair(symbol, st));
19183  break;
19184 
19185  case e_st_function : if (collect_functions_)
19186  symbol_name_list_
19187  .push_back(std::make_pair(symbol, st));
19188  break;
19189 
19190  default : return;
19191  }
19192  }
19193 
19194  inline void add_assignment(const std::string& symbol, const symbol_type st)
19195  {
19196  switch (st)
19197  {
19198  case e_st_variable :
19199  case e_st_vector :
19200  case e_st_string : if (collect_assignments_)
19201  assignment_name_list_
19202  .push_back(std::make_pair(symbol, st));
19203  break;
19204 
19205  default : return;
19206  }
19207  }
19208 
19209  std::size_t options_;
19218 
19219  friend class parser<T>;
19220  };
19221 
19223  {
19224  private:
19225 
19226  typedef std::set<std::string,details::ilesscompare> disabled_entity_set_t;
19227  typedef disabled_entity_set_t::iterator des_itr_t;
19228 
19229  public:
19230 
19232  {
19234  e_replacer = 1,
19235  e_joiner = 2,
19236  e_numeric_check = 4,
19237  e_bracket_check = 8,
19238  e_sequence_check = 16,
19239  e_commutative_check = 32,
19240  e_strength_reduction = 64,
19241  e_disable_vardef = 128,
19242  e_collect_vars = 256,
19243  e_collect_funcs = 512,
19244  e_collect_assings = 1024,
19245  e_disable_usr_on_rsrvd = 2048,
19246  e_disable_zero_return = 4096
19247  };
19248 
19250  {
19251  e_bf_unknown = 0,
19252  e_bf_abs , e_bf_acos , e_bf_acosh , e_bf_asin ,
19253  e_bf_asinh , e_bf_atan , e_bf_atan2 , e_bf_atanh ,
19254  e_bf_avg , e_bf_ceil , e_bf_clamp , e_bf_cos ,
19255  e_bf_cosh , e_bf_cot , e_bf_csc , e_bf_equal ,
19256  e_bf_erf , e_bf_erfc , e_bf_exp , e_bf_expm1 ,
19257  e_bf_floor , e_bf_frac , e_bf_hypot , e_bf_iclamp ,
19258  e_bf_like , e_bf_log , e_bf_log10 , e_bf_log1p ,
19259  e_bf_log2 , e_bf_logn , e_bf_mand , e_bf_max ,
19260  e_bf_min , e_bf_mod , e_bf_mor , e_bf_mul ,
19261  e_bf_ncdf , e_bf_pow , e_bf_root , e_bf_round ,
19262  e_bf_roundn , e_bf_sec , e_bf_sgn , e_bf_sin ,
19263  e_bf_sinc , e_bf_sinh , e_bf_sqrt , e_bf_sum ,
19264  e_bf_swap , e_bf_tan , e_bf_tanh , e_bf_trunc ,
19265  e_bf_not_equal , e_bf_inrange , e_bf_deg2grad , e_bf_deg2rad,
19266  e_bf_rad2deg , e_bf_grad2deg
19267  };
19268 
19270  {
19271  e_ctrl_unknown = 0,
19277  e_ctrl_return
19278  };
19279 
19281  {
19282  e_logic_unknown = 0,
19283  e_logic_and, e_logic_nand, e_logic_nor,
19284  e_logic_not, e_logic_or, e_logic_xnor,
19285  e_logic_xor, e_logic_scand, e_logic_scor
19286  };
19287 
19289  {
19290  e_arith_unknown = 0,
19291  e_arith_add, e_arith_sub, e_arith_mul,
19292  e_arith_div, e_arith_mod, e_arith_pow
19293  };
19294 
19296  {
19297  e_assign_unknown = 0,
19298  e_assign_assign, e_assign_addass, e_assign_subass,
19299  e_assign_mulass, e_assign_divass, e_assign_modass
19300  };
19301 
19303  {
19304  e_ineq_unknown = 0,
19305  e_ineq_lt, e_ineq_lte, e_ineq_eq,
19306  e_ineq_equal, e_ineq_ne, e_ineq_nequal,
19307  e_ineq_gte, e_ineq_gt
19308  };
19309 
19310  static const std::size_t compile_all_opts = e_replacer +
19311  e_joiner +
19312  e_numeric_check +
19313  e_bracket_check +
19314  e_sequence_check +
19315  e_commutative_check +
19316  e_strength_reduction;
19317 
19318  settings_store(const std::size_t compile_options = compile_all_opts)
19319  {
19320  load_compile_options(compile_options);
19321  }
19322 
19324  {
19325  disabled_func_set_.clear();
19326  return (*this);
19327  }
19328 
19330  {
19331  disabled_ctrl_set_.clear();
19332  return (*this);
19333  }
19334 
19336  {
19337  disabled_logic_set_.clear();
19338  return (*this);
19339  }
19340 
19342  {
19343  disabled_arithmetic_set_.clear();
19344  return (*this);
19345  }
19346 
19348  {
19349  disabled_assignment_set_.clear();
19350  return (*this);
19351  }
19352 
19354  {
19355  disabled_inequality_set_.clear();
19356  return (*this);
19357  }
19358 
19360  {
19361  disable_vardef_ = false;
19362  return (*this);
19363  }
19364 
19366  {
19369  std::insert_iterator<disabled_entity_set_t>
19370  (disabled_func_set_, disabled_func_set_.begin()));
19371  return (*this);
19372  }
19373 
19375  {
19378  std::insert_iterator<disabled_entity_set_t>
19379  (disabled_ctrl_set_, disabled_ctrl_set_.begin()));
19380  return (*this);
19381  }
19382 
19384  {
19387  std::insert_iterator<disabled_entity_set_t>
19388  (disabled_logic_set_, disabled_logic_set_.begin()));
19389  return (*this);
19390  }
19391 
19393  {
19396  std::insert_iterator<disabled_entity_set_t>
19397  (disabled_arithmetic_set_, disabled_arithmetic_set_.begin()));
19398  return (*this);
19399  }
19400 
19402  {
19405  std::insert_iterator<disabled_entity_set_t>
19406  (disabled_assignment_set_, disabled_assignment_set_.begin()));
19407  return (*this);
19408  }
19409 
19411  {
19414  std::insert_iterator<disabled_entity_set_t>
19415  (disabled_inequality_set_, disabled_inequality_set_.begin()));
19416  return (*this);
19417  }
19418 
19420  {
19421  disable_vardef_ = true;
19422  return (*this);
19423  }
19424 
19425  bool replacer_enabled () const { return enable_replacer_; }
19426  bool commutative_check_enabled () const { return enable_commutative_check_; }
19427  bool joiner_enabled () const { return enable_joiner_; }
19428  bool numeric_check_enabled () const { return enable_numeric_check_; }
19429  bool bracket_check_enabled () const { return enable_bracket_check_; }
19430  bool sequence_check_enabled () const { return enable_sequence_check_; }
19431  bool strength_reduction_enabled () const { return enable_strength_reduction_; }
19432  bool collect_variables_enabled () const { return enable_collect_vars_; }
19433  bool collect_functions_enabled () const { return enable_collect_funcs_; }
19434  bool collect_assignments_enabled() const { return enable_collect_assings_; }
19435  bool vardef_disabled () const { return disable_vardef_; }
19436  bool rsrvd_sym_usr_disabled () const { return disable_rsrvd_sym_usr_; }
19437  bool zero_return_disabled () const { return disable_zero_return_; }
19438 
19439  bool function_enabled(const std::string& function_name)
19440  {
19441  if (disabled_func_set_.empty())
19442  return true;
19443  else
19444  return (disabled_func_set_.end() == disabled_func_set_.find(function_name));
19445  }
19446 
19447  bool control_struct_enabled(const std::string& control_struct)
19448  {
19449  if (disabled_ctrl_set_.empty())
19450  return true;
19451  else
19452  return (disabled_ctrl_set_.end() == disabled_ctrl_set_.find(control_struct));
19453  }
19454 
19455  bool logic_enabled(const std::string& logic_operation)
19456  {
19457  if (disabled_logic_set_.empty())
19458  return true;
19459  else
19460  return (disabled_logic_set_.end() == disabled_logic_set_.find(logic_operation));
19461  }
19462 
19463  bool arithmetic_enabled(const details::operator_type& arithmetic_operation)
19464  {
19465  if (disabled_logic_set_.empty())
19466  return true;
19467  else
19468  return disabled_arithmetic_set_.end() == disabled_arithmetic_set_
19469  .find(arith_opr_to_string(arithmetic_operation));
19470  }
19471 
19473  {
19474  if (disabled_assignment_set_.empty())
19475  return true;
19476  else
19477  return disabled_assignment_set_.end() == disabled_assignment_set_
19478  .find(assign_opr_to_string(assignment));
19479  }
19480 
19482  {
19483  if (disabled_inequality_set_.empty())
19484  return true;
19485  else
19486  return disabled_inequality_set_.end() == disabled_inequality_set_
19487  .find(inequality_opr_to_string(inequality));
19488  }
19489 
19490  bool function_disabled(const std::string& function_name)
19491  {
19492  if (disabled_func_set_.empty())
19493  return false;
19494  else
19495  return (disabled_func_set_.end() != disabled_func_set_.find(function_name));
19496  }
19497 
19498  bool control_struct_disabled(const std::string& control_struct)
19499  {
19500  if (disabled_ctrl_set_.empty())
19501  return false;
19502  else
19503  return (disabled_ctrl_set_.end() != disabled_ctrl_set_.find(control_struct));
19504  }
19505 
19506  bool logic_disabled(const std::string& logic_operation)
19507  {
19508  if (disabled_logic_set_.empty())
19509  return false;
19510  else
19511  return (disabled_logic_set_.end() != disabled_logic_set_.find(logic_operation));
19512  }
19513 
19514  bool assignment_disabled(const details::operator_type assignment_operation)
19515  {
19516  if (disabled_assignment_set_.empty())
19517  return false;
19518  else
19519  return disabled_assignment_set_.end() != disabled_assignment_set_
19520  .find(assign_opr_to_string(assignment_operation));
19521  }
19522 
19523  bool arithmetic_disabled(const details::operator_type arithmetic_operation)
19524  {
19525  if (disabled_arithmetic_set_.empty())
19526  return false;
19527  else
19528  return disabled_arithmetic_set_.end() != disabled_arithmetic_set_
19529  .find(arith_opr_to_string(arithmetic_operation));
19530  }
19531 
19533  {
19534  if (disabled_inequality_set_.empty())
19535  return false;
19536  else
19537  return disabled_inequality_set_.end() != disabled_inequality_set_
19538  .find(inequality_opr_to_string(inequality));
19539  }
19540 
19542  {
19543  if (
19544  (e_bf_unknown != bf) &&
19545  (static_cast<std::size_t>(bf) < (details::base_function_list_size + 1))
19546  )
19547  {
19548  disabled_func_set_.insert(details::base_function_list[bf - 1]);
19549  }
19550 
19551  return (*this);
19552  }
19553 
19555  {
19556  if (
19557  (e_ctrl_unknown != ctrl_struct) &&
19558  (static_cast<std::size_t>(ctrl_struct) < (details::cntrl_struct_list_size + 1))
19559  )
19560  {
19561  disabled_ctrl_set_.insert(details::cntrl_struct_list[ctrl_struct - 1]);
19562  }
19563 
19564  return (*this);
19565  }
19566 
19568  {
19569  if (
19570  (e_logic_unknown != logic) &&
19571  (static_cast<std::size_t>(logic) < (details::logic_ops_list_size + 1))
19572  )
19573  {
19574  disabled_logic_set_.insert(details::logic_ops_list[logic - 1]);
19575  }
19576 
19577  return (*this);
19578  }
19579 
19581  {
19582  if (
19583  (e_arith_unknown != arithmetic) &&
19584  (static_cast<std::size_t>(arithmetic) < (details::arithmetic_ops_list_size + 1))
19585  )
19586  {
19587  disabled_arithmetic_set_.insert(details::arithmetic_ops_list[arithmetic - 1]);
19588  }
19589 
19590  return (*this);
19591  }
19592 
19594  {
19595  if (
19596  (e_assign_unknown != assignment) &&
19597  (static_cast<std::size_t>(assignment) < (details::assignment_ops_list_size + 1))
19598  )
19599  {
19600  disabled_assignment_set_.insert(details::assignment_ops_list[assignment - 1]);
19601  }
19602 
19603  return (*this);
19604  }
19605 
19607  {
19608  if (
19609  (e_ineq_unknown != inequality) &&
19610  (static_cast<std::size_t>(inequality) < (details::inequality_ops_list_size + 1))
19611  )
19612  {
19613  disabled_inequality_set_.insert(details::inequality_ops_list[inequality - 1]);
19614  }
19615 
19616  return (*this);
19617  }
19618 
19620  {
19621  if (
19622  (e_bf_unknown != bf) &&
19623  (static_cast<std::size_t>(bf) < (details::base_function_list_size + 1))
19624  )
19625  {
19626  const des_itr_t itr = disabled_func_set_.find(details::base_function_list[bf - 1]);
19627 
19628  if (disabled_func_set_.end() != itr)
19629  {
19630  disabled_func_set_.erase(itr);
19631  }
19632  }
19633 
19634  return (*this);
19635  }
19636 
19638  {
19639  if (
19640  (e_ctrl_unknown != ctrl_struct) &&
19641  (static_cast<std::size_t>(ctrl_struct) < (details::cntrl_struct_list_size + 1))
19642  )
19643  {
19644  const des_itr_t itr = disabled_ctrl_set_.find(details::cntrl_struct_list[ctrl_struct - 1]);
19645 
19646  if (disabled_ctrl_set_.end() != itr)
19647  {
19648  disabled_ctrl_set_.erase(itr);
19649  }
19650  }
19651 
19652  return (*this);
19653  }
19654 
19656  {
19657  if (
19658  (e_logic_unknown != logic) &&
19659  (static_cast<std::size_t>(logic) < (details::logic_ops_list_size + 1))
19660  )
19661  {
19662  const des_itr_t itr = disabled_logic_set_.find(details::logic_ops_list[logic - 1]);
19663 
19664  if (disabled_logic_set_.end() != itr)
19665  {
19666  disabled_logic_set_.erase(itr);
19667  }
19668  }
19669 
19670  return (*this);
19671  }
19672 
19674  {
19675  if (
19676  (e_arith_unknown != arithmetic) &&
19677  (static_cast<std::size_t>(arithmetic) < (details::arithmetic_ops_list_size + 1))
19678  )
19679  {
19680  const des_itr_t itr = disabled_arithmetic_set_.find(details::arithmetic_ops_list[arithmetic - 1]);
19681 
19682  if (disabled_arithmetic_set_.end() != itr)
19683  {
19684  disabled_arithmetic_set_.erase(itr);
19685  }
19686  }
19687 
19688  return (*this);
19689  }
19690 
19692  {
19693  if (
19694  (e_assign_unknown != assignment) &&
19695  (static_cast<std::size_t>(assignment) < (details::assignment_ops_list_size + 1))
19696  )
19697  {
19698  const des_itr_t itr = disabled_assignment_set_.find(details::assignment_ops_list[assignment - 1]);
19699 
19700  if (disabled_assignment_set_.end() != itr)
19701  {
19702  disabled_assignment_set_.erase(itr);
19703  }
19704  }
19705 
19706  return (*this);
19707  }
19708 
19710  {
19711  if (
19712  (e_ineq_unknown != inequality) &&
19713  (static_cast<std::size_t>(inequality) < (details::inequality_ops_list_size + 1))
19714  )
19715  {
19716  const des_itr_t itr = disabled_inequality_set_.find(details::inequality_ops_list[inequality - 1]);
19717 
19718  if (disabled_inequality_set_.end() != itr)
19719  {
19720  disabled_inequality_set_.erase(itr);
19721  }
19722  }
19723 
19724  return (*this);
19725  }
19726 
19727  private:
19728 
19729  void load_compile_options(const std::size_t compile_options)
19730  {
19731  enable_replacer_ = (compile_options & e_replacer ) == e_replacer;
19732  enable_joiner_ = (compile_options & e_joiner ) == e_joiner;
19733  enable_numeric_check_ = (compile_options & e_numeric_check ) == e_numeric_check;
19734  enable_bracket_check_ = (compile_options & e_bracket_check ) == e_bracket_check;
19735  enable_sequence_check_ = (compile_options & e_sequence_check ) == e_sequence_check;
19736  enable_commutative_check_ = (compile_options & e_commutative_check ) == e_commutative_check;
19737  enable_strength_reduction_ = (compile_options & e_strength_reduction ) == e_strength_reduction;
19738  enable_collect_vars_ = (compile_options & e_collect_vars ) == e_collect_vars;
19739  enable_collect_funcs_ = (compile_options & e_collect_funcs ) == e_collect_funcs;
19740  enable_collect_assings_ = (compile_options & e_collect_assings ) == e_collect_assings;
19741  disable_vardef_ = (compile_options & e_disable_vardef ) == e_disable_vardef;
19742  disable_rsrvd_sym_usr_ = (compile_options & e_disable_usr_on_rsrvd) == e_disable_usr_on_rsrvd;
19743  disable_zero_return_ = (compile_options & e_disable_zero_return ) == e_disable_zero_return;
19744  }
19745 
19747  {
19748  switch (opr)
19749  {
19750  case details::e_assign : return ":=";
19751  case details::e_addass : return "+=";
19752  case details::e_subass : return "-=";
19753  case details::e_mulass : return "*=";
19754  case details::e_divass : return "/=";
19755  case details::e_modass : return "%=";
19756  default : return "";
19757  }
19758  }
19759 
19761  {
19762  switch (opr)
19763  {
19764  case details::e_add : return "+";
19765  case details::e_sub : return "-";
19766  case details::e_mul : return "*";
19767  case details::e_div : return "/";
19768  case details::e_mod : return "%";
19769  default : return "";
19770  }
19771  }
19772 
19774  {
19775  switch (opr)
19776  {
19777  case details::e_lt : return "<";
19778  case details::e_lte : return "<=";
19779  case details::e_eq : return "==";
19780  case details::e_equal : return "=";
19781  case details::e_ne : return "!=";
19782  case details::e_nequal: return "<>";
19783  case details::e_gte : return ">=";
19784  case details::e_gt : return ">";
19785  default : return "";
19786  }
19787  }
19788 
19802 
19809 
19810  friend class parser<T>;
19811  };
19812 
19814 
19815  parser(const settings_t& settings = settings_t())
19816  : settings_(settings),
19817  resolve_unknown_symbol_(false),
19818  results_context_(0),
19819  unknown_symbol_resolver_(reinterpret_cast<unknown_symbol_resolver*>(0)),
19820  #ifdef _MSC_VER
19821  #pragma warning(push)
19822  #pragma warning (disable:4355)
19823  #endif
19824  sem_(*this),
19825  #ifdef _MSC_VER
19826  #pragma warning(pop)
19827  #endif
19828  operator_joiner_2_(2),
19829  operator_joiner_3_(3)
19830  {
19831  init_precompilation();
19832 
19833  load_operations_map (base_ops_map_ );
19834  load_unary_operations_map (unary_op_map_ );
19835  load_binary_operations_map (binary_op_map_ );
19836  load_inv_binary_operations_map(inv_binary_op_map_);
19837  load_sf3_map (sf3_map_ );
19838  load_sf4_map (sf4_map_ );
19839 
19840  expression_generator_.init_synthesize_map();
19841  expression_generator_.set_parser(*this);
19842  expression_generator_.set_uom(unary_op_map_);
19843  expression_generator_.set_bom(binary_op_map_);
19844  expression_generator_.set_ibom(inv_binary_op_map_);
19845  expression_generator_.set_sf3m(sf3_map_);
19846  expression_generator_.set_sf4m(sf4_map_);
19847  expression_generator_.set_strength_reduction_state(settings_.strength_reduction_enabled());
19848  }
19849 
19851  {}
19852 
19853  inline void init_precompilation()
19854  {
19855  if (settings_.collect_variables_enabled())
19856  dec_.collect_variables() = true;
19857 
19858  if (settings_.collect_functions_enabled())
19859  dec_.collect_functions() = true;
19860 
19861  if (settings_.collect_assignments_enabled())
19862  dec_.collect_assignments() = true;
19863 
19864  if (settings_.replacer_enabled())
19865  {
19866  symbol_replacer_.clear();
19867  symbol_replacer_.add_replace("true" ,"1",lexer::token::e_number);
19868  symbol_replacer_.add_replace("false","0",lexer::token::e_number);
19869  helper_assembly_.token_modifier_list.clear();
19870  helper_assembly_.register_modifier(&symbol_replacer_);
19871  }
19872 
19873  if (settings_.commutative_check_enabled())
19874  {
19875  for (std::size_t i = 0; i < details::reserved_words_size; ++i)
19876  {
19877  commutative_inserter_.ignore_symbol(details::reserved_words[i]);
19878  }
19879 
19880  helper_assembly_.token_inserter_list.clear();
19881  helper_assembly_.register_inserter(&commutative_inserter_);
19882  }
19883 
19884  if (settings_.joiner_enabled())
19885  {
19886  helper_assembly_.token_joiner_list.clear();
19887  helper_assembly_.register_joiner(&operator_joiner_2_);
19888  helper_assembly_.register_joiner(&operator_joiner_3_);
19889  }
19890 
19891  if (
19892  settings_.numeric_check_enabled () ||
19893  settings_.bracket_check_enabled () ||
19894  settings_.sequence_check_enabled()
19895  )
19896  {
19897  helper_assembly_.token_scanner_list.clear();
19898 
19899  if (settings_.numeric_check_enabled())
19900  {
19901  helper_assembly_.register_scanner(&numeric_checker_);
19902  }
19903 
19904  if (settings_.bracket_check_enabled())
19905  {
19906  helper_assembly_.register_scanner(&bracket_checker_);
19907  }
19908 
19909  if (settings_.sequence_check_enabled())
19910  {
19911  helper_assembly_.register_scanner(&sequence_validator_);
19912  }
19913  }
19914  }
19915 
19916  inline bool compile(const std::string& expression_string, expression<T>& expr)
19917  {
19918  state_ .reset();
19919  error_list_ .clear();
19920  brkcnt_list_ .clear();
19921  synthesis_error_.clear();
19922  sem_ .cleanup();
19923 
19924  return_cleanup();
19925 
19926  expression_generator_.set_allocator(node_allocator_);
19927 
19928  if (expression_string.empty())
19929  {
19930  set_error(
19932  "ERR000 - Empty expression!",
19934 
19935  return false;
19936  }
19937 
19938  if (!init(expression_string))
19939  {
19940  process_lexer_errors();
19941  return false;
19942  }
19943 
19944  if (lexer().empty())
19945  {
19946  set_error(
19948  "ERR001 - Empty expression!",
19950 
19951  return false;
19952  }
19953 
19954  if (!run_assemblies())
19955  {
19956  return false;
19957  }
19958 
19959  symtab_store_.symtab_list_ = expr.get_symbol_table_list();
19960  dec_.clear();
19961 
19962  lexer().begin();
19963 
19964  next_token();
19965 
19966  expression_node_ptr e = parse_corpus();
19967 
19968  if ((0 != e) && (token_t::e_eof == current_token().type))
19969  {
19970  bool* retinvk_ptr = 0;
19971 
19972  if (state_.return_stmt_present)
19973  {
19974  dec_.return_present_ = true;
19975 
19976  e = expression_generator_
19977  .return_envelope(e,results_context_,retinvk_ptr);
19978  }
19979 
19980  expr.set_expression(e);
19981  expr.set_retinvk(retinvk_ptr);
19982 
19983  register_local_vars(expr);
19984  register_return_results(expr);
19985 
19986  return !(!expr);
19987  }
19988  else
19989  {
19990  if (error_list_.empty())
19991  {
19992  set_error(
19994  current_token(),
19995  "ERR002 - Invalid expression encountered",
19997  }
19998 
19999  dec_.clear ();
20000  sem_.cleanup ();
20001  return_cleanup();
20002 
20003  if ((0 != e) && branch_deletable(e))
20004  {
20005  destroy_node(e);
20006  }
20007 
20008  return false;
20009  }
20010  }
20011 
20012  inline expression_t compile(const std::string& expression_string, symbol_table_t& symtab)
20013  {
20014  expression_t expr;
20015 
20016  expr.register_symbol_table(symtab);
20017 
20018  compile(expression_string,expr);
20019 
20020  return expr;
20021  }
20022 
20024  {
20025  for (std::size_t i = 0; i < lexer().size(); ++i)
20026  {
20027  if (lexer()[i].is_error())
20028  {
20029  std::string diagnostic = "ERR003 - ";
20030 
20031  switch (lexer()[i].type)
20032  {
20033  case lexer::token::e_error : diagnostic += "General token error";
20034  break;
20035 
20036  case lexer::token::e_err_symbol : diagnostic += "Symbol error";
20037  break;
20038 
20039  case lexer::token::e_err_number : diagnostic += "Invalid numeric token";
20040  break;
20041 
20042  case lexer::token::e_err_string : diagnostic += "Invalid string token";
20043  break;
20044 
20045  case lexer::token::e_err_sfunc : diagnostic += "Invalid special function token";
20046  break;
20047 
20048  default : diagnostic += "Unknown compiler error";
20049  }
20050 
20051  set_error(
20053  lexer()[i],
20054  diagnostic + ": " + lexer()[i].value,
20056  }
20057  }
20058  }
20059 
20060  inline bool run_assemblies()
20061  {
20062  if (settings_.commutative_check_enabled())
20063  {
20064  helper_assembly_.run_inserters(lexer());
20065  }
20066 
20067  if (settings_.joiner_enabled())
20068  {
20069  helper_assembly_.run_joiners(lexer());
20070  }
20071 
20072  if (settings_.replacer_enabled())
20073  {
20074  helper_assembly_.run_modifiers(lexer());
20075  }
20076 
20077  if (
20078  settings_.numeric_check_enabled () ||
20079  settings_.bracket_check_enabled () ||
20080  settings_.sequence_check_enabled()
20081  )
20082  {
20083  if (!helper_assembly_.run_scanners(lexer()))
20084  {
20085  if (helper_assembly_.error_token_scanner)
20086  {
20087  lexer::helper::bracket_checker* bracket_checker_ptr = 0;
20088  lexer::helper::numeric_checker* numeric_checker_ptr = 0;
20089  lexer::helper::sequence_validator* sequence_validator_ptr = 0;
20090 
20091  if (0 != (bracket_checker_ptr = dynamic_cast<lexer::helper::bracket_checker*>(helper_assembly_.error_token_scanner)))
20092  {
20093  set_error(
20095  bracket_checker_ptr->error_token(),
20096  "ERR004 - Mismatched brackets: '" + bracket_checker_ptr->error_token().value + "'",
20098  }
20099  else if (0 != (numeric_checker_ptr = dynamic_cast<lexer::helper::numeric_checker*>(helper_assembly_.error_token_scanner)))
20100  {
20101  for (std::size_t i = 0; i < numeric_checker_ptr->error_count(); ++i)
20102  {
20103  lexer::token error_token = lexer()[numeric_checker_ptr->error_index(i)];
20104 
20105  set_error(
20107  error_token,
20108  "ERR005 - Invalid numeric token: '" + error_token.value + "'",
20110  }
20111 
20112  if (numeric_checker_ptr->error_count())
20113  {
20114  numeric_checker_ptr->clear_errors();
20115  }
20116  }
20117  else if (0 != (sequence_validator_ptr = dynamic_cast<lexer::helper::sequence_validator*>(helper_assembly_.error_token_scanner)))
20118  {
20119  for (std::size_t i = 0; i < sequence_validator_ptr->error_count(); ++i)
20120  {
20121  std::pair<lexer::token,lexer::token> error_token = sequence_validator_ptr->error(i);
20122 
20123  set_error(
20125  error_token.first,
20126  "ERR006 - Invalid token sequence: '" +
20127  error_token.first.value + "' and '" +
20128  error_token.second.value + "'",
20130  }
20131 
20132  if (sequence_validator_ptr->error_count())
20133  {
20134  sequence_validator_ptr->clear_errors();
20135  }
20136  }
20137  }
20138 
20139  return false;
20140  }
20141  }
20142 
20143  return true;
20144  }
20145 
20147  {
20148  return settings_;
20149  }
20150 
20151  inline parser_error::type get_error(const std::size_t& index)
20152  {
20153  if (index < error_list_.size())
20154  return error_list_[index];
20155  else
20156  throw std::invalid_argument("parser::get_error() - Invalid error index specificed");
20157  }
20158 
20159  inline std::string error() const
20160  {
20161  if (!error_list_.empty())
20162  {
20163  return error_list_[0].diagnostic;
20164  }
20165  else
20166  return std::string("No Error");
20167  }
20168 
20169  inline std::size_t error_count() const
20170  {
20171  return error_list_.size();
20172  }
20173 
20175  {
20176  return dec_;
20177  }
20178 
20179  inline bool replace_symbol(const std::string& old_symbol, const std::string& new_symbol)
20180  {
20181  if (!settings_.replacer_enabled())
20182  return false;
20183  else if (details::is_reserved_word(old_symbol))
20184  return false;
20185  else
20186  return symbol_replacer_.add_replace(old_symbol,new_symbol,lexer::token::e_symbol);
20187  }
20188 
20189  inline bool remove_replace_symbol(const std::string& symbol)
20190  {
20191  if (!settings_.replacer_enabled())
20192  return false;
20193  else if (details::is_reserved_word(symbol))
20194  return false;
20195  else
20196  return symbol_replacer_.remove(symbol);
20197  }
20198 
20199  inline void enable_unknown_symbol_resolver(unknown_symbol_resolver* usr = reinterpret_cast<unknown_symbol_resolver*>(0))
20200  {
20201  resolve_unknown_symbol_ = true;
20202 
20203  if (usr)
20204  unknown_symbol_resolver_ = usr;
20205  else
20206  unknown_symbol_resolver_ = &default_usr_;
20207  }
20208 
20210  {
20211  enable_unknown_symbol_resolver(&usr);
20212  }
20213 
20215  {
20216  resolve_unknown_symbol_ = false;
20217  unknown_symbol_resolver_ = &default_usr_;
20218  }
20219 
20220  private:
20221 
20222  inline bool valid_base_operation(const std::string& symbol)
20223  {
20224  const std::size_t length = symbol.size();
20225 
20226  if (
20227  (length < 3) || // Shortest base op symbol length
20228  (length > 9) // Longest base op symbol length
20229  )
20230  return false;
20231  else
20232  return settings_.function_enabled(symbol) &&
20233  (base_ops_map_.end() != base_ops_map_.find(symbol));
20234  }
20235 
20236  inline bool valid_vararg_operation(const std::string& symbol)
20237  {
20238  static const std::string s_sum = "sum" ;
20239  static const std::string s_mul = "mul" ;
20240  static const std::string s_avg = "avg" ;
20241  static const std::string s_min = "min" ;
20242  static const std::string s_max = "max" ;
20243  static const std::string s_mand = "mand";
20244  static const std::string s_mor = "mor" ;
20245  static const std::string s_multi = "~" ;
20246  static const std::string s_mswitch = "[*]" ;
20247 
20248  return
20249  (
20250  details::imatch(symbol,s_sum ) ||
20251  details::imatch(symbol,s_mul ) ||
20252  details::imatch(symbol,s_avg ) ||
20253  details::imatch(symbol,s_min ) ||
20254  details::imatch(symbol,s_max ) ||
20255  details::imatch(symbol,s_mand ) ||
20256  details::imatch(symbol,s_mor ) ||
20257  details::imatch(symbol,s_multi ) ||
20258  details::imatch(symbol,s_mswitch)
20259  ) &&
20260  settings_.function_enabled(symbol);
20261  }
20262 
20264  {
20265  return settings_.arithmetic_disabled(operation);
20266  }
20267 
20269  {
20270  return settings_.assignment_disabled(operation);
20271  }
20272 
20274  {
20275  return settings_.inequality_disabled(operation);
20276  }
20277 
20278  #ifdef exprtk_enable_debugging
20279  inline void next_token()
20280  {
20281  std::string ct_str = current_token().value;
20282  parser_helper::next_token();
20283  std::string depth(2 * state_.scope_depth,' ');
20284  exprtk_debug(("%s"
20285  "prev[%s] --> curr[%s]\n",
20286  depth.c_str(),
20287  ct_str.c_str(),
20288  current_token().value.c_str()));
20289  }
20290  #endif
20291 
20293  {
20294  std::vector<expression_node_ptr> arg_list;
20295  std::vector<bool> side_effect_list;
20296 
20297  expression_node_ptr result = error_node();
20298 
20299  scoped_vec_delete<expression_node_t> sdd((*this),arg_list);
20300 
20301  lexer::token begin_token;
20302  lexer::token end_token;
20303 
20304  for ( ; ; )
20305  {
20306  state_.side_effect_present = false;
20307 
20308  begin_token = current_token();
20309 
20310  expression_node_ptr arg = parse_expression();
20311 
20312  if (0 == arg)
20313  {
20314  if (error_list_.empty())
20315  {
20316  set_error(
20318  current_token(),
20319  "ERR007 - Invalid expression encountered",
20321  }
20322 
20323  return error_node();
20324  }
20325  else
20326  {
20327  arg_list.push_back(arg);
20328 
20329  side_effect_list.push_back(state_.side_effect_present);
20330 
20331  end_token = current_token();
20332 
20333  std::string sub_expr = construct_subexpr(begin_token,end_token);
20334 
20335  exprtk_debug(("parse_corpus(%02d) Subexpr: %s\n",
20336  static_cast<int>(arg_list.size() - 1),
20337  sub_expr.c_str()));
20338 
20339  exprtk_debug(("parse_corpus(%02d) - Side effect present: %s\n",
20340  static_cast<int>(arg_list.size() - 1),
20341  state_.side_effect_present ? "true" : "false"));
20342 
20343  exprtk_debug(("-------------------------------------------------\n"));
20344  }
20345 
20346  if (lexer().finished())
20347  break;
20348  else if (token_is(token_t::e_eof,prsrhlpr_t::e_hold))
20349  {
20350  if (lexer().finished())
20351  break;
20352  else
20353  next_token();
20354  }
20355  }
20356 
20357  if (
20358  !arg_list.empty() &&
20359  is_return_node(arg_list.back())
20360  )
20361  {
20362  dec_.final_stmt_return_ = true;
20363  }
20364 
20365  result = simplify(arg_list,side_effect_list);
20366 
20367  sdd.delete_ptr = (0 == result);
20368 
20369  return result;
20370  }
20371 
20372  std::string construct_subexpr(lexer::token& begin_token, lexer::token& end_token)
20373  {
20374  std::string result = lexer().substr(begin_token.position,end_token.position);
20375 
20376  for (std::size_t i = 0; i < result.size(); ++i)
20377  {
20378  if (details::is_whitespace(result[i])) result[i] = ' ';
20379  }
20380 
20381  return result;
20382  }
20383 
20384  static const precedence_level default_precedence = e_level00;
20385 
20386  struct state_t
20387  {
20388  inline void set(const precedence_level& l,
20389  const precedence_level& r,
20390  const details::operator_type& o)
20391  {
20392  left = l;
20393  right = r;
20394  operation = o;
20395  }
20396 
20397  inline void reset()
20398  {
20399  left = e_level00;
20400  right = e_level00;
20401  operation = details::e_default;
20402  }
20403 
20407  };
20408 
20410  {
20411  expression_node_ptr expression = parse_branch(precedence);
20412 
20413  if (0 == expression)
20414  {
20415  return error_node();
20416  }
20417 
20418  bool break_loop = false;
20419 
20420  state_t current_state;
20421 
20422  for ( ; ; )
20423  {
20424  current_state.reset();
20425 
20426  switch (current_token().type)
20427  {
20428  case token_t::e_assign : current_state.set(e_level00,e_level00,details::e_assign); break;
20429  case token_t::e_addass : current_state.set(e_level00,e_level00,details::e_addass); break;
20430  case token_t::e_subass : current_state.set(e_level00,e_level00,details::e_subass); break;
20431  case token_t::e_mulass : current_state.set(e_level00,e_level00,details::e_mulass); break;
20432  case token_t::e_divass : current_state.set(e_level00,e_level00,details::e_divass); break;
20433  case token_t::e_modass : current_state.set(e_level00,e_level00,details::e_modass); break;
20434  case token_t::e_swap : current_state.set(e_level00,e_level00,details::e_swap ); break;
20435  case token_t::e_lt : current_state.set(e_level05,e_level06,details:: e_lt); break;
20436  case token_t::e_lte : current_state.set(e_level05,e_level06,details:: e_lte); break;
20437  case token_t::e_eq : current_state.set(e_level05,e_level06,details:: e_eq); break;
20438  case token_t::e_ne : current_state.set(e_level05,e_level06,details:: e_ne); break;
20439  case token_t::e_gte : current_state.set(e_level05,e_level06,details:: e_gte); break;
20440  case token_t::e_gt : current_state.set(e_level05,e_level06,details:: e_gt); break;
20441  case token_t::e_add : current_state.set(e_level07,e_level08,details:: e_add); break;
20442  case token_t::e_sub : current_state.set(e_level07,e_level08,details:: e_sub); break;
20443  case token_t::e_div : current_state.set(e_level10,e_level11,details:: e_div); break;
20444  case token_t::e_mul : current_state.set(e_level10,e_level11,details:: e_mul); break;
20445  case token_t::e_mod : current_state.set(e_level10,e_level11,details:: e_mod); break;
20446  case token_t::e_pow : current_state.set(e_level12,e_level12,details:: e_pow); break;
20447  default : if (token_t::e_symbol == current_token().type)
20448  {
20449  static const std::string s_and = "and";
20450  static const std::string s_nand = "nand";
20451  static const std::string s_or = "or";
20452  static const std::string s_nor = "nor";
20453  static const std::string s_xor = "xor";
20454  static const std::string s_xnor = "xnor";
20455  static const std::string s_in = "in";
20456  static const std::string s_like = "like";
20457  static const std::string s_ilike = "ilike";
20458  static const std::string s_and1 = "&";
20459  static const std::string s_or1 = "|";
20460  static const std::string s_not = "not";
20461 
20462  if (details::imatch(current_token().value,s_and))
20463  {
20464  current_state.set(e_level03, e_level04, details::e_and);
20465  break;
20466  }
20467  else if (details::imatch(current_token().value,s_and1))
20468  {
20469  #ifndef exprtk_disable_sc_andor
20470  current_state.set(e_level03, e_level04, details::e_scand);
20471  #else
20472  current_state.set(e_level03, e_level04, details::e_and);
20473  #endif
20474  break;
20475  }
20476  else if (details::imatch(current_token().value,s_nand))
20477  {
20478  current_state.set(e_level03, e_level04, details::e_nand);
20479  break;
20480  }
20481  else if (details::imatch(current_token().value,s_or))
20482  {
20483  current_state.set(e_level01, e_level02, details::e_or);
20484  break;
20485  }
20486  else if (details::imatch(current_token().value,s_or1))
20487  {
20488  #ifndef exprtk_disable_sc_andor
20489  current_state.set(e_level01, e_level02, details::e_scor);
20490  #else
20491  current_state.set(e_level01, e_level02, details::e_or);
20492  #endif
20493  break;
20494  }
20495  else if (details::imatch(current_token().value,s_nor))
20496  {
20497  current_state.set(e_level01, e_level02, details::e_nor);
20498  break;
20499  }
20500  else if (details::imatch(current_token().value,s_xor))
20501  {
20502  current_state.set(e_level01, e_level02, details::e_xor);
20503  break;
20504  }
20505  else if (details::imatch(current_token().value,s_xnor))
20506  {
20507  current_state.set(e_level01, e_level02, details::e_xnor);
20508  break;
20509  }
20510  else if (details::imatch(current_token().value,s_in))
20511  {
20512  current_state.set(e_level04, e_level04, details::e_in);
20513  break;
20514  }
20515  else if (details::imatch(current_token().value,s_like))
20516  {
20517  current_state.set(e_level04, e_level04, details::e_like);
20518  break;
20519  }
20520  else if (details::imatch(current_token().value,s_ilike))
20521  {
20522  current_state.set(e_level04, e_level04, details::e_ilike);
20523  break;
20524  }
20525  else if (details::imatch(current_token().value,s_not))
20526  {
20527  break;
20528  }
20529  }
20530 
20531  break_loop = true;
20532  }
20533 
20534  if (break_loop)
20535  {
20536  parse_pending_string_rangesize(expression);
20537  break;
20538  }
20539  else if (current_state.left < precedence)
20540  break;
20541 
20542  lexer::token prev_token = current_token();
20543 
20544  next_token();
20545 
20546  expression_node_ptr right_branch = error_node();
20547  expression_node_ptr new_expression = error_node();
20548 
20549  if (is_invalid_arithmetic_operation(current_state.operation))
20550  {
20551  free_node(node_allocator_,expression);
20552 
20553  set_error(
20555  prev_token,
20556  "ERR008 - Invalid arithmetic operation '" + details::to_str(current_state.operation) + "'",
20558 
20559  return error_node();
20560  }
20561  else if (is_invalid_inequality_operation(current_state.operation))
20562  {
20563  free_node(node_allocator_,expression);
20564 
20565  set_error(
20567  prev_token,
20568  "ERR009 - Invalid inequality operation '" + details::to_str(current_state.operation) + "'",
20570 
20571  return error_node();
20572  }
20573  else if (is_invalid_assignment_operation(current_state.operation))
20574  {
20575  free_node(node_allocator_,expression);
20576 
20577  set_error(
20579  prev_token,
20580  "ERR010 - Invalid assignment operation '" + details::to_str(current_state.operation) + "'",
20582 
20583  return error_node();
20584  }
20585 
20586  if (0 != (right_branch = parse_expression(current_state.right)))
20587  {
20588  if (
20589  details::is_return_node( expression) ||
20590  details::is_return_node(right_branch)
20591  )
20592  {
20593  free_node(node_allocator_, expression);
20594  free_node(node_allocator_, right_branch);
20595 
20596  set_error(
20598  prev_token,
20599  "ERR011 - Return statements cannot be part of sub-expressions",
20601 
20602  return error_node();
20603  }
20604 
20605  new_expression = expression_generator_
20606  (
20607  current_state.operation,
20608  expression,
20609  right_branch
20610  );
20611  }
20612 
20613  if (0 == new_expression)
20614  {
20615  if (error_list_.empty())
20616  {
20617  set_error(
20619  prev_token,
20620  !synthesis_error_.empty() ?
20621  synthesis_error_ :
20622  "ERR012 - General parsing error at token: '" + prev_token.value + "'",
20624  }
20625 
20626  free_node(node_allocator_, expression);
20627  free_node(node_allocator_, right_branch);
20628 
20629  return error_node();
20630  }
20631  else
20632  {
20633  if (
20634  token_is(token_t::e_ternary,prsrhlpr_t::e_hold) &&
20635  (precedence == e_level00)
20636  )
20637  {
20638  expression = parse_ternary_conditional_statement(new_expression);
20639  }
20640  else
20641  expression = new_expression;
20642 
20643  parse_pending_string_rangesize(expression);
20644  }
20645  }
20646 
20647  return expression;
20648  }
20649 
20651  {
20652  {
20654  ubn_t* n = dynamic_cast<ubn_t*>(node);
20655 
20656  if (n)
20657  {
20658  expression_node_ptr un_r = n->branch(0);
20659  n->release();
20660  free_node(node_allocator_,node);
20661  node = un_r;
20662 
20663  return true;
20664  }
20665  }
20666 
20667  {
20669 
20670  uvn_t* n = dynamic_cast<uvn_t*>(node);
20671 
20672  if (n)
20673  {
20674  const T& v = n->v();
20675  expression_node_ptr return_node = error_node();
20676 
20677  if (
20678  (0 != (return_node = symtab_store_.get_variable(v))) ||
20679  (0 != (return_node = sem_ .get_variable(v)))
20680  )
20681  {
20682  free_node(node_allocator_,node);
20683  node = return_node;
20684 
20685  return true;
20686  }
20687  else
20688  {
20689  set_error(
20691  current_token(),
20692  "ERR013 - Failed to find variable node in symbol table",
20694 
20695  free_node(node_allocator_,node);
20696 
20697  return false;
20698  }
20699  }
20700  }
20701 
20702  return false;
20703  }
20704 
20706  {
20707  return reinterpret_cast<expression_node_ptr>(0);
20708  }
20709 
20710  template <typename Type, std::size_t N>
20712  {
20713  typedef Type* ptr_t;
20714 
20716  : delete_ptr(true),
20717  parser_(pr),
20718  p_(&p)
20719  {}
20720 
20722  : delete_ptr(true),
20723  parser_(pr),
20724  p_(&p[0])
20725  {}
20726 
20728  {
20729  if (delete_ptr)
20730  {
20731  for (std::size_t i = 0; i < N; ++i)
20732  {
20733  free_node(parser_.node_allocator_,p_[i]);
20734  }
20735  }
20736  }
20737 
20741 
20742  private:
20743 
20744  scoped_delete<Type,N>& operator=(const scoped_delete<Type,N>&);
20745  };
20746 
20747  template <typename Type>
20749  {
20750  typedef Type* ptr_t;
20751 
20752  scoped_deq_delete(parser<T>& pr, std::deque<ptr_t>& deq)
20753  : delete_ptr(true),
20754  parser_(pr),
20755  deq_(deq)
20756  {}
20757 
20759  {
20760  if (delete_ptr && !deq_.empty())
20761  {
20762  for (std::size_t i = 0; i < deq_.size(); ++i)
20763  {
20764  free_node(parser_.node_allocator_,deq_[i]);
20765  }
20766 
20767  deq_.clear();
20768  }
20769  }
20770 
20773  std::deque<ptr_t>& deq_;
20774 
20775  private:
20776 
20778  };
20779 
20780  template <typename Type>
20782  {
20783  typedef Type* ptr_t;
20784 
20785  scoped_vec_delete(parser<T>& pr, std::vector<ptr_t>& vec)
20786  : delete_ptr(true),
20787  parser_(pr),
20788  vec_(vec)
20789  {}
20790 
20792  {
20793  if (delete_ptr && !vec_.empty())
20794  {
20795  for (std::size_t i = 0; i < vec_.size(); ++i)
20796  {
20797  free_node(parser_.node_allocator_,vec_[i]);
20798  }
20799 
20800  vec_.clear();
20801  }
20802  }
20803 
20806  std::vector<ptr_t>& vec_;
20807 
20808  private:
20809 
20811  };
20812 
20814  {
20816  : b(bb)
20817  { b = !b; }
20818 
20820  { b = !b; }
20821 
20822  bool& b;
20823  };
20824 
20826  {
20828  : b(bb),
20829  original_value_(bb)
20830  {}
20831 
20833  {
20834  b = b || original_value_;
20835  }
20836 
20837  bool& b;
20839  };
20840 
20841  inline expression_node_ptr parse_function_invocation(ifunction<T>* function, const std::string& function_name)
20842  {
20843  expression_node_ptr func_node = reinterpret_cast<expression_node_ptr>(0);
20844 
20845  switch (function->param_count)
20846  {
20847  case 0 : func_node = parse_function_call_0 (function,function_name); break;
20848  case 1 : func_node = parse_function_call< 1>(function,function_name); break;
20849  case 2 : func_node = parse_function_call< 2>(function,function_name); break;
20850  case 3 : func_node = parse_function_call< 3>(function,function_name); break;
20851  case 4 : func_node = parse_function_call< 4>(function,function_name); break;
20852  case 5 : func_node = parse_function_call< 5>(function,function_name); break;
20853  case 6 : func_node = parse_function_call< 6>(function,function_name); break;
20854  case 7 : func_node = parse_function_call< 7>(function,function_name); break;
20855  case 8 : func_node = parse_function_call< 8>(function,function_name); break;
20856  case 9 : func_node = parse_function_call< 9>(function,function_name); break;
20857  case 10 : func_node = parse_function_call<10>(function,function_name); break;
20858  case 11 : func_node = parse_function_call<11>(function,function_name); break;
20859  case 12 : func_node = parse_function_call<12>(function,function_name); break;
20860  case 13 : func_node = parse_function_call<13>(function,function_name); break;
20861  case 14 : func_node = parse_function_call<14>(function,function_name); break;
20862  case 15 : func_node = parse_function_call<15>(function,function_name); break;
20863  case 16 : func_node = parse_function_call<16>(function,function_name); break;
20864  case 17 : func_node = parse_function_call<17>(function,function_name); break;
20865  case 18 : func_node = parse_function_call<18>(function,function_name); break;
20866  case 19 : func_node = parse_function_call<19>(function,function_name); break;
20867  case 20 : func_node = parse_function_call<20>(function,function_name); break;
20868  default : {
20869  set_error(
20871  current_token(),
20872  "ERR014 - Invalid number of parameters for function: '" + function_name + "'",
20874 
20875  return error_node();
20876  }
20877  }
20878 
20879  if (func_node)
20880  return func_node;
20881  else
20882  {
20883  set_error(
20885  current_token(),
20886  "ERR015 - Failed to generate call to function: '" + function_name + "'",
20888 
20889  return error_node();
20890  }
20891  }
20892 
20893  template <std::size_t NumberofParameters>
20894  inline expression_node_ptr parse_function_call(ifunction<T>* function, const std::string& function_name)
20895  {
20896  #ifdef _MSC_VER
20897  #pragma warning(push)
20898  #pragma warning(disable: 4127)
20899  #endif
20900  if (0 == NumberofParameters)
20901  {
20902  set_error(
20904  current_token(),
20905  "ERR016 - Expecting ifunction '" + function_name + "' to have non-zero parameter count",
20907 
20908  return error_node();
20909  }
20910  #ifdef _MSC_VER
20911  #pragma warning(pop)
20912  #endif
20913 
20914  expression_node_ptr branch[NumberofParameters];
20915  expression_node_ptr result = error_node();
20916 
20917  std::fill_n(branch, NumberofParameters, reinterpret_cast<expression_node_ptr>(0));
20918 
20920 
20921  next_token();
20922 
20923  if (!token_is(token_t::e_lbracket))
20924  {
20925  set_error(
20927  current_token(),
20928  "ERR017 - Expecting argument list for function: '" + function_name + "'",
20930 
20931  return error_node();
20932  }
20933 
20934  for (int i = 0; i < static_cast<int>(NumberofParameters); ++i)
20935  {
20936  branch[i] = parse_expression();
20937 
20938  if (0 == branch[i])
20939  {
20940  set_error(
20942  current_token(),
20943  "ERR018 - Failed to parse argument " + details::to_str(i) + " for function: '" + function_name + "'",
20945 
20946  return error_node();
20947  }
20948  else if (i < static_cast<int>(NumberofParameters - 1))
20949  {
20950  if (!token_is(token_t::e_comma))
20951  {
20952  set_error(
20954  current_token(),
20955  "ERR019 - Invalid number of arguments for function: '" + function_name + "'",
20957 
20958  return error_node();
20959  }
20960  }
20961  }
20962 
20963  if (!token_is(token_t::e_rbracket))
20964  {
20965  set_error(
20967  current_token(),
20968  "ERR020 - Invalid number of arguments for function: '" + function_name + "'",
20970 
20971  return error_node();
20972  }
20973  else
20974  result = expression_generator_.function(function,branch);
20975 
20976  sd.delete_ptr = false;
20977 
20978  return result;
20979  }
20980 
20981  inline expression_node_ptr parse_function_call_0(ifunction<T>* function, const std::string& function_name)
20982  {
20983  expression_node_ptr result = expression_generator_.function(function);
20984 
20985  state_.side_effect_present = function->has_side_effects();
20986 
20987  next_token();
20988 
20989  if (
20990  token_is(token_t::e_lbracket) &&
20991  !token_is(token_t::e_rbracket)
20992  )
20993  {
20994  set_error(
20996  current_token(),
20997  "ERR021 - Expecting '()' to proceed call to function: '" + function_name + "'",
20999 
21000  free_node(node_allocator_,result);
21001 
21002  return error_node();
21003  }
21004  else
21005  return result;
21006  }
21007 
21008  template <std::size_t MaxNumberofParameters>
21009  inline std::size_t parse_base_function_call(expression_node_ptr (&param_list)[MaxNumberofParameters], const std::string& function_name = "")
21010  {
21011  std::fill_n(param_list, MaxNumberofParameters, reinterpret_cast<expression_node_ptr>(0));
21012 
21014 
21015  next_token();
21016 
21017  if (!token_is(token_t::e_lbracket))
21018  {
21019  set_error(
21021  current_token(),
21022  "ERR022 - Expected a '(' at start of function call to '" + function_name +
21023  "', instead got: '" + current_token().value + "'",
21025 
21026  return 0;
21027  }
21028 
21029  if (token_is(token_t::e_rbracket, e_hold))
21030  {
21031  set_error(
21033  current_token(),
21034  "ERR023 - Expected at least one input parameter for function call '" + function_name + "'",
21036 
21037  return 0;
21038  }
21039 
21040  std::size_t param_index = 0;
21041 
21042  for (; param_index < MaxNumberofParameters; ++param_index)
21043  {
21044  param_list[param_index] = parse_expression();
21045 
21046  if (0 == param_list[param_index])
21047  return 0;
21048  else if (token_is(token_t::e_rbracket))
21049  {
21050  sd.delete_ptr = false;
21051  break;
21052  }
21053  else if (token_is(token_t::e_comma))
21054  continue;
21055  else
21056  {
21057  set_error(
21059  current_token(),
21060  "ERR024 - Expected a ',' between function input parameters, instead got: '" + current_token().value + "'",
21062 
21063  return 0;
21064  }
21065  }
21066 
21067  if (sd.delete_ptr)
21068  {
21069  set_error(
21071  current_token(),
21072  "ERR025 - Invalid number of input parameters passed to function '" + function_name + "'",
21074 
21075  return 0;
21076  }
21077 
21078  return (param_index + 1);
21079  }
21080 
21082  {
21083  typedef std::pair<base_ops_map_t::iterator,base_ops_map_t::iterator> map_range_t;
21084 
21085  const std::string operation_name = current_token().value;
21086  const token_t diagnostic_token = current_token();
21087 
21088  map_range_t itr_range = base_ops_map_.equal_range(operation_name);
21089 
21090  if (0 == std::distance(itr_range.first,itr_range.second))
21091  {
21092  set_error(
21094  diagnostic_token,
21095  "ERR026 - No entry found for base operation: " + operation_name,
21097 
21098  return error_node();
21099  }
21100 
21101  static const std::size_t MaxNumberofParameters = 4;
21102  expression_node_ptr param_list[MaxNumberofParameters] = {0};
21103 
21104  const std::size_t parameter_count = parse_base_function_call(param_list, operation_name);
21105 
21106  if ((parameter_count > 0) && (parameter_count <= MaxNumberofParameters))
21107  {
21108  for (base_ops_map_t::iterator itr = itr_range.first; itr != itr_range.second; ++itr)
21109  {
21110  details::base_operation_t& operation = itr->second;
21111 
21112  if (operation.num_params == parameter_count)
21113  {
21114  switch (parameter_count)
21115  {
21116  #define base_opr_case(N) \
21117  case N : { \
21118  expression_node_ptr pl##N[N] = {0}; \
21119  std::copy(param_list, param_list + N, pl##N); \
21120  lodge_symbol(operation_name, e_st_function); \
21121  return expression_generator_(operation.type, pl##N); \
21122  } \
21123 
21124  base_opr_case(1)
21125  base_opr_case(2)
21126  base_opr_case(3)
21127  base_opr_case(4)
21128  #undef base_opr_case
21129  }
21130  }
21131  }
21132  }
21133 
21134  for (std::size_t i = 0; i < MaxNumberofParameters; ++i)
21135  {
21136  free_node(node_allocator_, param_list[i]);
21137  }
21138 
21139  set_error(
21141  diagnostic_token,
21142  "ERR027 - Invalid number of input parameters for call to function: '" + operation_name + "'",
21144 
21145  return error_node();
21146  }
21147 
21149  {
21150  // Parse: [if][(][condition][,][consequent][,][alternative][)]
21151 
21152  expression_node_ptr consequent = error_node();
21153  expression_node_ptr alternative = error_node();
21154 
21155  bool result = true;
21156 
21157  if (!token_is(token_t::e_comma))
21158  {
21159  set_error(
21161  current_token(),
21162  "ERR028 - Expected ',' between if-statement condition and consequent",
21164  result = false;
21165  }
21166  else if (0 == (consequent = parse_expression()))
21167  {
21168  set_error(
21170  current_token(),
21171  "ERR029 - Failed to parse consequent for if-statement",
21173  result = false;
21174  }
21175  else if (!token_is(token_t::e_comma))
21176  {
21177  set_error(
21179  current_token(),
21180  "ERR030 - Expected ',' between if-statement consequent and alternative",
21182  result = false;
21183  }
21184  else if (0 == (alternative = parse_expression()))
21185  {
21186  set_error(
21188  current_token(),
21189  "ERR031 - Failed to parse alternative for if-statement",
21191  result = false;
21192  }
21193  else if (!token_is(token_t::e_rbracket))
21194  {
21195  set_error(
21197  current_token(),
21198  "ERR032 - Expected ')' at the end of if-statement",
21200  result = false;
21201  }
21202 
21203  #ifndef exprtk_disable_string_capabilities
21204  if (result)
21205  {
21206  const bool consq_is_str = is_generally_string_node( consequent);
21207  const bool alter_is_str = is_generally_string_node(alternative);
21208 
21209  if (consq_is_str || alter_is_str)
21210  {
21211  if (consq_is_str && alter_is_str)
21212  {
21213  return expression_generator_
21214  .conditional_string(condition,consequent,alternative);
21215  }
21216 
21217  set_error(
21219  current_token(),
21220  "ERR033 - Return types of ternary if-statement differ",
21222 
21223  result = false;
21224  }
21225  }
21226  #endif
21227 
21228  if (!result)
21229  {
21230  free_node(node_allocator_, condition);
21231  free_node(node_allocator_, consequent);
21232  free_node(node_allocator_,alternative);
21233 
21234  return error_node();
21235  }
21236  else
21237  return expression_generator_
21238  .conditional(condition,consequent,alternative);
21239  }
21240 
21242  {
21243  expression_node_ptr consequent = error_node();
21244  expression_node_ptr alternative = error_node();
21245 
21246  bool result = true;
21247 
21248  if (token_is(token_t::e_lcrlbracket,prsrhlpr_t::e_hold))
21249  {
21250  if (0 == (consequent = parse_multi_sequence("if-statement-01")))
21251  {
21252  set_error(
21254  current_token(),
21255  "ERR034 - Failed to parse body of consequent for if-statement",
21257 
21258  result = false;
21259  }
21260  }
21261  else
21262  {
21263  if (
21264  settings_.commutative_check_enabled() &&
21265  token_is(token_t::e_mul,prsrhlpr_t::e_hold)
21266  )
21267  {
21268  next_token();
21269  }
21270 
21271  if (0 != (consequent = parse_expression()))
21272  {
21273  if (!token_is(token_t::e_eof))
21274  {
21275  set_error(
21277  current_token(),
21278  "ERR035 - Expected ';' at the end of the consequent for if-statement",
21280 
21281  result = false;
21282  }
21283  }
21284  else
21285  {
21286  set_error(
21288  current_token(),
21289  "ERR036 - Failed to parse body of consequent for if-statement",
21291 
21292  result = false;
21293  }
21294  }
21295 
21296  if (result)
21297  {
21298  if (details::imatch(current_token().value,"else"))
21299  {
21300  next_token();
21301 
21302  if (token_is(token_t::e_lcrlbracket,prsrhlpr_t::e_hold))
21303  {
21304  if (0 == (alternative = parse_multi_sequence("else-statement-01")))
21305  {
21306  set_error(
21308  current_token(),
21309  "ERR037 - Failed to parse body of the 'else' for if-statement",
21311 
21312  result = false;
21313  }
21314  }
21315  else if (details::imatch(current_token().value,"if"))
21316  {
21317  if (0 == (alternative = parse_conditional_statement()))
21318  {
21319  set_error(
21321  current_token(),
21322  "ERR038 - Failed to parse body of if-else statement",
21324 
21325  result = false;
21326  }
21327  }
21328  else if (0 != (alternative = parse_expression()))
21329  {
21330  if (!token_is(token_t::e_eof))
21331  {
21332  set_error(
21334  current_token(),
21335  "ERR039 - Expected ';' at the end of the 'else-if' for the if-statement",
21337 
21338  result = false;
21339  }
21340  }
21341  else
21342  {
21343  set_error(
21345  current_token(),
21346  "ERR040 - Failed to parse body of the 'else' for if-statement",
21348 
21349  result = false;
21350  }
21351  }
21352  }
21353 
21354  #ifndef exprtk_disable_string_capabilities
21355  if (result)
21356  {
21357  const bool consq_is_str = is_generally_string_node( consequent);
21358  const bool alter_is_str = is_generally_string_node(alternative);
21359 
21360  if (consq_is_str || alter_is_str)
21361  {
21362  if (consq_is_str && alter_is_str)
21363  {
21364  return expression_generator_
21365  .conditional_string(condition, consequent, alternative);
21366  }
21367 
21368  set_error(
21370  current_token(),
21371  "ERR041 - Return types of ternary if-statement differ",
21373 
21374  result = false;
21375  }
21376  }
21377  #endif
21378 
21379  if (!result)
21380  {
21381  free_node(node_allocator_, condition);
21382  free_node(node_allocator_, consequent);
21383  free_node(node_allocator_, alternative);
21384 
21385  return error_node();
21386  }
21387  else
21388  return expression_generator_
21389  .conditional(condition, consequent, alternative);
21390  }
21391 
21393  {
21394  expression_node_ptr condition = error_node();
21395 
21396  next_token();
21397 
21398  if (!token_is(token_t::e_lbracket))
21399  {
21400  set_error(
21402  current_token(),
21403  "ERR042 - Expected '(' at start of if-statement, instead got: '" + current_token().value + "'",
21405 
21406  return error_node();
21407  }
21408  else if (0 == (condition = parse_expression()))
21409  {
21410  set_error(
21412  current_token(),
21413  "ERR043 - Failed to parse condition for if-statement",
21415 
21416  return error_node();
21417  }
21418  else if (token_is(token_t::e_comma,prsrhlpr_t::e_hold))
21419  {
21420  // if (x,y,z)
21421  return parse_conditional_statement_01(condition);
21422  }
21423  else if (token_is(token_t::e_rbracket))
21424  {
21425  // 00. if (x) y;
21426  // 01. if (x) y; else z;
21427  // 02. if (x) y; else {z0; ... zn;}
21428  // 03. if (x) y; else if (z) w;
21429  // 04. if (x) y; else if (z) w; else u;
21430  // 05. if (x) y; else if (z) w; else {u0; ... un;}
21431  // 06. if (x) y; else if (z) {w0; ... wn;}
21432  // 07. if (x) {y0; ... yn;}
21433  // 08. if (x) {y0; ... yn;} else z;
21434  // 09. if (x) {y0; ... yn;} else {z0; ... zn;};
21435  // 10. if (x) {y0; ... yn;} else if (z) w;
21436  // 11. if (x) {y0; ... yn;} else if (z) w; else u;
21437  // 12. if (x) {y0; ... nex;} else if (z) w; else {u0 ... un;}
21438  // 13. if (x) {y0; ... yn;} else if (z) {w0; ... wn;}
21439  return parse_conditional_statement_02(condition);
21440  }
21441 
21442  set_error(
21444  current_token(),
21445  "ERR044 - Invalid if-statement",
21447 
21448  free_node(node_allocator_,condition);
21449 
21450  return error_node();
21451  }
21452 
21454  {
21455  // Parse: [condition][?][consequent][:][alternative]
21456  expression_node_ptr consequent = error_node();
21457  expression_node_ptr alternative = error_node();
21458 
21459  bool result = true;
21460 
21461  if (0 == condition)
21462  {
21463  set_error(
21465  current_token(),
21466  "ERR045 - Encountered invalid condition branch for ternary if-statement",
21468 
21469  return error_node();
21470  }
21471  else if (!token_is(token_t::e_ternary))
21472  {
21473  set_error(
21475  current_token(),
21476  "ERR046 - Expected '?' after condition of ternary if-statement",
21478 
21479  result = false;
21480  }
21481  else if (0 == (consequent = parse_expression()))
21482  {
21483  set_error(
21485  current_token(),
21486  "ERR047 - Failed to parse consequent for ternary if-statement",
21488 
21489  result = false;
21490  }
21491  else if (!token_is(token_t::e_colon))
21492  {
21493  set_error(
21495  current_token(),
21496  "ERR048 - Expected ':' between ternary if-statement consequent and alternative",
21498 
21499  result = false;
21500  }
21501  else if (0 == (alternative = parse_expression()))
21502  {
21503  set_error(
21505  current_token(),
21506  "ERR049 - Failed to parse alternative for ternary if-statement",
21508 
21509  result = false;
21510  }
21511 
21512  #ifndef exprtk_disable_string_capabilities
21513  if (result)
21514  {
21515  const bool consq_is_str = is_generally_string_node( consequent);
21516  const bool alter_is_str = is_generally_string_node(alternative);
21517 
21518  if (consq_is_str || alter_is_str)
21519  {
21520  if (consq_is_str && alter_is_str)
21521  {
21522  return expression_generator_
21523  .conditional_string(condition, consequent, alternative);
21524  }
21525 
21526  set_error(
21528  current_token(),
21529  "ERR050 - Return types of ternary if-statement differ",
21531 
21532  result = false;
21533  }
21534  }
21535  #endif
21536 
21537  if (!result)
21538  {
21539  free_node(node_allocator_, condition);
21540  free_node(node_allocator_, consequent);
21541  free_node(node_allocator_, alternative);
21542 
21543  return error_node();
21544  }
21545  else
21546  return expression_generator_
21547  .conditional(condition, consequent, alternative);
21548  }
21549 
21551  {
21552  // Parse: [while][(][test expr][)][{][expression][}]
21553  expression_node_ptr condition = error_node();
21554  expression_node_ptr branch = error_node();
21555  expression_node_ptr result_node = error_node();
21556 
21557  bool result = true;
21558 
21559  next_token();
21560 
21561  if (!token_is(token_t::e_lbracket))
21562  {
21563  set_error(
21565  current_token(),
21566  "ERR051 - Expected '(' at start of while-loop condition statement",
21568 
21569  return error_node();
21570  }
21571  else if (0 == (condition = parse_expression()))
21572  {
21573  set_error(
21575  current_token(),
21576  "ERR052 - Failed to parse condition for while-loop",
21578 
21579  return error_node();
21580  }
21581  else if (!token_is(token_t::e_rbracket))
21582  {
21583  set_error(
21585  current_token(),
21586  "ERR053 - Expected ')' at end of while-loop condition statement",
21588 
21589  result = false;
21590  }
21591 
21592  brkcnt_list_.push_front(false);
21593 
21594  if (result)
21595  {
21596  if (0 == (branch = parse_multi_sequence("while-loop")))
21597  {
21598  set_error(
21600  current_token(),
21601  "ERR054 - Failed to parse body of while-loop"));
21602  result = false;
21603  }
21604  else if (0 == (result_node = expression_generator_.while_loop(condition,
21605  branch,
21606  brkcnt_list_.front())))
21607  {
21608  set_error(
21610  current_token(),
21611  "ERR055 - Failed to synthesize while-loop",
21613 
21614  result = false;
21615  }
21616  }
21617 
21618  if (!result)
21619  {
21620  free_node(node_allocator_, branch);
21621  free_node(node_allocator_, condition);
21622  free_node(node_allocator_, result_node);
21623 
21624  brkcnt_list_.pop_front();
21625 
21626  return error_node();
21627  }
21628  else
21629  return result_node;
21630  }
21631 
21633  {
21634  // Parse: [repeat][{][expression][}][until][(][test expr][)]
21635  expression_node_ptr condition = error_node();
21636  expression_node_ptr branch = error_node();
21637  next_token();
21638 
21639  std::vector<expression_node_ptr> arg_list;
21640  std::vector<bool> side_effect_list;
21641 
21642  scoped_vec_delete<expression_node_t> sdd((*this),arg_list);
21643 
21644  brkcnt_list_.push_front(false);
21645 
21646  if (details::imatch(current_token().value,"until"))
21647  {
21648  next_token();
21649  branch = node_allocator_.allocate<details::null_node<T> >();
21650  }
21651  else
21652  {
21653  token_t::token_type seperator = token_t::e_eof;
21654 
21655  scope_handler sh(*this);
21656 
21657  scoped_bool_or_restorer sbr(state_.side_effect_present);
21658 
21659  for ( ; ; )
21660  {
21661  state_.side_effect_present = false;
21662 
21663  expression_node_ptr arg = parse_expression();
21664 
21665  if (0 == arg)
21666  return error_node();
21667  else
21668  {
21669  arg_list.push_back(arg);
21670  side_effect_list.push_back(state_.side_effect_present);
21671  }
21672 
21673  if (details::imatch(current_token().value,"until"))
21674  {
21675  next_token();
21676  break;
21677  }
21678 
21679  bool is_next_until = peek_token_is(token_t::e_symbol) &&
21680  peek_token_is("until");
21681 
21682  if (!token_is(seperator) && is_next_until)
21683  {
21684  set_error(
21686  current_token(),
21687  "ERR056 - Expected '" + token_t::to_str(seperator) + "' in body of repeat until loop",
21689 
21690  return error_node();
21691  }
21692 
21693  if (details::imatch(current_token().value,"until"))
21694  {
21695  next_token();
21696  break;
21697  }
21698  }
21699 
21700  branch = simplify(arg_list,side_effect_list);
21701 
21702  sdd.delete_ptr = (0 == branch);
21703 
21704  if (sdd.delete_ptr)
21705  {
21706  brkcnt_list_.pop_front();
21707 
21708  set_error(
21710  current_token(),
21711  "ERR057 - Failed to parse body of repeat until loop",
21713 
21714  return error_node();
21715  }
21716  }
21717 
21718  if (!token_is(token_t::e_lbracket))
21719  {
21720  brkcnt_list_.pop_front();
21721 
21722  set_error(
21724  current_token(),
21725  "ERR058 - Expected '(' before condition statement of repeat until loop",
21727 
21728  free_node(node_allocator_,branch);
21729 
21730  return error_node();
21731  }
21732  else if (0 == (condition = parse_expression()))
21733  {
21734  brkcnt_list_.pop_front();
21735 
21736  set_error(
21738  current_token(),
21739  "ERR059 - Failed to parse condition for repeat until loop",
21741 
21742  free_node(node_allocator_,branch);
21743 
21744  return error_node();
21745  }
21746  else if (!token_is(token_t::e_rbracket))
21747  {
21748  set_error(
21750  current_token(),
21751  "ERR060 - Expected ')' after condition of repeat until loop",
21753 
21754  free_node(node_allocator_, branch);
21755  free_node(node_allocator_, condition);
21756 
21757  brkcnt_list_.pop_front();
21758 
21759  return error_node();
21760  }
21761 
21762  expression_node_ptr result;
21763 
21764  result = expression_generator_
21765  .repeat_until_loop(condition, branch, brkcnt_list_.front());
21766 
21767  if (0 == result)
21768  {
21769  set_error(
21771  current_token(),
21772  "ERR061 - Failed to synthesize repeat until loop",
21774 
21775  free_node(node_allocator_,condition);
21776 
21777  brkcnt_list_.pop_front();
21778 
21779  return error_node();
21780  }
21781  else
21782  {
21783  brkcnt_list_.pop_front();
21784  return result;
21785  }
21786  }
21787 
21789  {
21790  expression_node_ptr initialiser = error_node();
21791  expression_node_ptr condition = error_node();
21792  expression_node_ptr incrementor = error_node();
21793  expression_node_ptr loop_body = error_node();
21794 
21795  scope_element* se = 0;
21796  bool result = true;
21797  std::string loop_counter_symbol;
21798 
21799  next_token();
21800 
21801  scope_handler sh(*this);
21802 
21803  if (!token_is(token_t::e_lbracket))
21804  {
21805  set_error(
21807  current_token(),
21808  "ERR062 - Expected '(' at start of for-loop",
21810 
21811  return error_node();
21812  }
21813 
21814  if (!token_is(token_t::e_eof))
21815  {
21816  if (
21817  !token_is(token_t::e_symbol,prsrhlpr_t::e_hold) &&
21818  details::imatch(current_token().value,"var")
21819  )
21820  {
21821  next_token();
21822 
21823  if (!token_is(token_t::e_symbol,prsrhlpr_t::e_hold))
21824  {
21825  set_error(
21827  current_token(),
21828  "ERR063 - Expected a variable at the start of initialiser section of for-loop",
21830 
21831  return error_node();
21832  }
21833  else if (!peek_token_is(token_t::e_assign))
21834  {
21835  set_error(
21837  current_token(),
21838  "ERR064 - Expected variable assignment of initialiser section of for-loop",
21840 
21841  return error_node();
21842  }
21843 
21844  loop_counter_symbol = current_token().value;
21845 
21846  se = &sem_.get_element(loop_counter_symbol);
21847 
21848  if ((se->name == loop_counter_symbol) && se->active)
21849  {
21850  set_error(
21852  current_token(),
21853  "ERR065 - For-loop variable '" + loop_counter_symbol+ "' is being shadowed by a previous declaration",
21855 
21856  return error_node();
21857  }
21858  else if (!symtab_store_.is_variable(loop_counter_symbol))
21859  {
21860  if (
21861  !se->active &&
21862  (se->name == loop_counter_symbol) &&
21863  (se->type == scope_element::e_variable)
21864  )
21865  {
21866  se->active = true;
21867  se->ref_count++;
21868  }
21869  else
21870  {
21871  scope_element nse;
21872  nse.name = loop_counter_symbol;
21873  nse.active = true;
21874  nse.ref_count = 1;
21875  nse.type = scope_element::e_variable;
21876  nse.depth = state_.scope_depth;
21877  nse.data = new T(T(0));
21878  nse.var_node = node_allocator_.allocate<variable_node_t>(*(T*)(nse.data));
21879 
21880  if (!sem_.add_element(nse))
21881  {
21882  set_error(
21884  current_token(),
21885  "ERR066 - Failed to add new local variable '" + loop_counter_symbol + "' to SEM",
21887 
21888  sem_.free_element(nse);
21889 
21890  result = false;
21891  }
21892  else
21893  {
21894  exprtk_debug(("parse_for_loop() - INFO - Added new local variable: %s\n",nse.name.c_str()));
21895 
21896  state_.activate_side_effect("parse_for_loop()");
21897  }
21898  }
21899  }
21900  }
21901 
21902  if (0 == (initialiser = parse_expression()))
21903  {
21904  set_error(
21906  current_token(),
21907  "ERR067 - Failed to parse initialiser of for-loop",
21909 
21910  result = false;
21911  }
21912  else if (!token_is(token_t::e_eof))
21913  {
21914  set_error(
21916  current_token(),
21917  "ERR068 - Expected ';' after initialiser of for-loop",
21919 
21920  result = false;
21921  }
21922  }
21923 
21924  if (!token_is(token_t::e_eof))
21925  {
21926  if (0 == (condition = parse_expression()))
21927  {
21928  set_error(
21930  current_token(),
21931  "ERR069 - Failed to parse condition of for-loop",
21933 
21934  result = false;
21935  }
21936  else if (!token_is(token_t::e_eof))
21937  {
21938  set_error(
21940  current_token(),
21941  "ERR070 - Expected ';' after condition section of for-loop",
21943 
21944  result = false;
21945  }
21946  }
21947 
21948  if (!token_is(token_t::e_rbracket))
21949  {
21950  if (0 == (incrementor = parse_expression()))
21951  {
21952  set_error(
21954  current_token(),
21955  "ERR071 - Failed to parse incrementor of for-loop",
21957 
21958  result = false;
21959  }
21960  else if (!token_is(token_t::e_rbracket))
21961  {
21962  set_error(
21964  current_token(),
21965  "ERR072 - Expected ')' after incrementor section of for-loop",
21967 
21968  result = false;
21969  }
21970  }
21971 
21972  if (result)
21973  {
21974  brkcnt_list_.push_front(false);
21975 
21976  if (0 == (loop_body = parse_multi_sequence("for-loop")))
21977  {
21978  set_error(
21980  current_token(),
21981  "ERR073 - Failed to parse body of for-loop",
21983 
21984  result = false;
21985  }
21986  }
21987 
21988  if (!result)
21989  {
21990  if (se)
21991  {
21992  se->ref_count--;
21993  }
21994 
21995  sem_.cleanup();
21996 
21997  free_node(node_allocator_, initialiser);
21998  free_node(node_allocator_, condition);
21999  free_node(node_allocator_, incrementor);
22000  free_node(node_allocator_, loop_body);
22001 
22002  if (!brkcnt_list_.empty())
22003  {
22004  brkcnt_list_.pop_front();
22005  }
22006 
22007  return error_node();
22008  }
22009  else
22010  {
22011  expression_node_ptr result_node =
22012  expression_generator_.for_loop(initialiser,
22013  condition,
22014  incrementor,
22015  loop_body,
22016  brkcnt_list_.front());
22017  brkcnt_list_.pop_front();
22018 
22019  return result_node;
22020  }
22021  }
22022 
22024  {
22025  std::vector<expression_node_ptr> arg_list;
22026  expression_node_ptr result = error_node();
22027 
22028  if (!details::imatch(current_token().value,"switch"))
22029  {
22030  set_error(
22032  current_token(),
22033  "ERR074 - Expected keyword 'switch'",
22035 
22036  return error_node();
22037  }
22038 
22039  scoped_vec_delete<expression_node_t> svd((*this),arg_list);
22040 
22041  next_token();
22042 
22043  if (!token_is(token_t::e_lcrlbracket))
22044  {
22045  set_error(
22047  current_token(),
22048  "ERR075 - Expected '{' for call to switch statement",
22050 
22051  return error_node();
22052  }
22053 
22054  for ( ; ; )
22055  {
22056  if (!details::imatch("case",current_token().value))
22057  {
22058  set_error(
22060  current_token(),
22061  "ERR076 - Expected either a 'case' or 'default' statement",
22063 
22064  return error_node();
22065  }
22066 
22067  next_token();
22068 
22069  expression_node_ptr condition = parse_expression();
22070 
22071  if (0 == condition)
22072  return error_node();
22073  else if (!token_is(token_t::e_colon))
22074  {
22075  set_error(
22077  current_token(),
22078  "ERR077 - Expected ':' for case of switch statement",
22080 
22081  return error_node();
22082  }
22083 
22084  expression_node_ptr consequent = parse_expression();
22085 
22086  if (0 == consequent)
22087  return error_node();
22088  else if (!token_is(token_t::e_eof))
22089  {
22090  set_error(
22092  current_token(),
22093  "ERR078 - Expected ';' at end of case for switch statement",
22095 
22096  return error_node();
22097  }
22098 
22099  // Can we optimise away the case statement?
22100  if (is_constant_node(condition) && is_false(condition))
22101  {
22102  free_node(node_allocator_, condition);
22103  free_node(node_allocator_, consequent);
22104  }
22105  else
22106  {
22107  arg_list.push_back( condition);
22108  arg_list.push_back(consequent);
22109  }
22110 
22111  if (details::imatch("default",current_token().value))
22112  {
22113  next_token();
22114  if (!token_is(token_t::e_colon))
22115  {
22116  set_error(
22118  current_token(),
22119  "ERR079 - Expected ':' for default of switch statement",
22121 
22122  return error_node();
22123  }
22124 
22125  expression_node_ptr default_statement = error_node();
22126 
22127  if (token_is(token_t::e_lcrlbracket,prsrhlpr_t::e_hold))
22128  default_statement = parse_multi_sequence("switch-default");
22129  else
22130  default_statement = parse_expression();
22131 
22132  if (0 == default_statement)
22133  return error_node();
22134  else if (!token_is(token_t::e_eof))
22135  {
22136  free_node(node_allocator_,default_statement);
22137 
22138  set_error(
22140  current_token(),
22141  "ERR080 - Expected ';' at end of default for switch statement",
22143 
22144  return error_node();
22145  }
22146 
22147  arg_list.push_back(default_statement);
22148  break;
22149  }
22150  }
22151 
22152  if (!token_is(token_t::e_rcrlbracket))
22153  {
22154  set_error(
22156  current_token(),
22157  "ERR081 - Expected '}' at end of switch statement",
22159 
22160  return error_node();
22161  }
22162 
22163  result = expression_generator_.switch_statement(arg_list);
22164 
22165  svd.delete_ptr = (0 == result);
22166 
22167  return result;
22168  }
22169 
22171  {
22172  std::vector<expression_node_ptr> arg_list;
22173  expression_node_ptr result = error_node();
22174 
22175  if (!details::imatch(current_token().value,"[*]"))
22176  {
22177  set_error(
22179  current_token(),
22180  "ERR082 - Expected token '[*]'",
22182 
22183  return error_node();
22184  }
22185 
22186  scoped_vec_delete<expression_node_t> svd((*this),arg_list);
22187 
22188  next_token();
22189 
22190  if (!token_is(token_t::e_lcrlbracket))
22191  {
22192  set_error(
22194  current_token(),
22195  "ERR083 - Expected '{' for call to [*] statement",
22197 
22198  return error_node();
22199  }
22200 
22201  for ( ; ; )
22202  {
22203  if (!details::imatch("case",current_token().value))
22204  {
22205  set_error(
22207  current_token(),
22208  "ERR084 - Expected a 'case' statement for multi-switch",
22210 
22211  return error_node();
22212  }
22213 
22214  next_token();
22215 
22216  expression_node_ptr condition = parse_expression();
22217 
22218  if (0 == condition)
22219  return error_node();
22220 
22221  if (!token_is(token_t::e_colon))
22222  {
22223  set_error(
22225  current_token(),
22226  "ERR085 - Expected ':' for case of [*] statement",
22228 
22229  return error_node();
22230  }
22231 
22232  expression_node_ptr consequent = parse_expression();
22233 
22234  if (0 == consequent)
22235  return error_node();
22236 
22237  if (!token_is(token_t::e_eof))
22238  {
22239  set_error(
22241  current_token(),
22242  "ERR086 - Expected ';' at end of case for [*] statement",
22244 
22245  return error_node();
22246  }
22247 
22248  // Can we optimise away the case statement?
22249  if (is_constant_node(condition) && is_false(condition))
22250  {
22251  free_node(node_allocator_, condition);
22252  free_node(node_allocator_, consequent);
22253  }
22254  else
22255  {
22256  arg_list.push_back(condition);
22257  arg_list.push_back(consequent);
22258  }
22259 
22260  if (token_is(token_t::e_rcrlbracket,prsrhlpr_t::e_hold))
22261  {
22262  break;
22263  }
22264  }
22265 
22266  if (!token_is(token_t::e_rcrlbracket))
22267  {
22268  set_error(
22270  current_token(),
22271  "ERR087 - Expected '}' at end of [*] statement",
22273 
22274  return error_node();
22275  }
22276 
22277  result = expression_generator_.multi_switch_statement(arg_list);
22278 
22279  svd.delete_ptr = (0 == result);
22280 
22281  return result;
22282  }
22283 
22285  {
22286  std::vector<expression_node_ptr> arg_list;
22287  expression_node_ptr result = error_node();
22288 
22290  const std::string symbol = current_token().value;
22291 
22292  if (details::imatch(symbol,"~"))
22293  {
22294  next_token();
22295  return parse_multi_sequence();
22296  }
22297  else if (details::imatch(symbol,"[*]"))
22298  {
22299  return parse_multi_switch_statement();
22300  }
22301  else if (details::imatch(symbol, "avg" )) opt_type = details::e_avg ;
22302  else if (details::imatch(symbol, "mand")) opt_type = details::e_mand;
22303  else if (details::imatch(symbol, "max" )) opt_type = details::e_max ;
22304  else if (details::imatch(symbol, "min" )) opt_type = details::e_min ;
22305  else if (details::imatch(symbol, "mor" )) opt_type = details::e_mor ;
22306  else if (details::imatch(symbol, "mul" )) opt_type = details::e_prod;
22307  else if (details::imatch(symbol, "sum" )) opt_type = details::e_sum ;
22308  else
22309  {
22310  set_error(
22312  current_token(),
22313  "ERR088 - Unsupported vararg function: " + symbol,
22315 
22316  return error_node();
22317  }
22318 
22319  scoped_vec_delete<expression_node_t> sdd((*this),arg_list);
22320 
22321  lodge_symbol(symbol,e_st_function);
22322 
22323  next_token();
22324 
22325  if (!token_is(token_t::e_lbracket))
22326  {
22327  set_error(
22329  current_token(),
22330  "ERR089 - Expected '(' for call to vararg function: " + symbol,
22332 
22333  return error_node();
22334  }
22335 
22336  for ( ; ; )
22337  {
22338  expression_node_ptr arg = parse_expression();
22339 
22340  if (0 == arg)
22341  return error_node();
22342  else
22343  arg_list.push_back(arg);
22344 
22345  if (token_is(token_t::e_rbracket))
22346  break;
22347  else if (!token_is(token_t::e_comma))
22348  {
22349  set_error(
22351  current_token(),
22352  "ERR090 - Expected ',' for call to vararg function: " + symbol,
22354 
22355  return error_node();
22356  }
22357  }
22358 
22359  result = expression_generator_.vararg_function(opt_type,arg_list);
22360 
22361  sdd.delete_ptr = (0 == result);
22362  return result;
22363  }
22364 
22365  #ifndef exprtk_disable_string_capabilities
22367  {
22368  if (!token_is(token_t::e_lsqrbracket))
22369  {
22370  set_error(
22372  current_token(),
22373  "ERR091 - Expected '[' as start of string range definition",
22375 
22376  free_node(node_allocator_,expression);
22377 
22378  return error_node();
22379  }
22380  else if (token_is(token_t::e_rsqrbracket))
22381  {
22382  return node_allocator_.allocate<details::string_size_node<T> >(expression);
22383  }
22384 
22385  range_t rp;
22386 
22387  if (!parse_range(rp,true))
22388  {
22389  free_node(node_allocator_,expression);
22390 
22391  return error_node();
22392  }
22393 
22394  expression_node_ptr result = expression_generator_(expression,rp);
22395 
22396  if (0 == result)
22397  {
22398  set_error(
22400  current_token(),
22401  "ERR092 - Failed to generate string range node",
22403 
22404  free_node(node_allocator_,expression);
22405  }
22406 
22407  rp.clear();
22408 
22409  return result;
22410  }
22411  #else
22412  inline expression_node_ptr parse_string_range_statement(expression_node_ptr&)
22413  {
22414  return error_node();
22415  }
22416  #endif
22417 
22419  {
22420  // Allow no more than 100 range calls, eg: s[][][]...[][]
22421  const std::size_t max_rangesize_parses = 100;
22422 
22423  std::size_t i = 0;
22424 
22425  while
22426  (
22427  (0 != expression) &&
22428  (i++ < max_rangesize_parses) &&
22429  error_list_.empty() &&
22430  is_generally_string_node(expression) &&
22431  token_is(token_t::e_lsqrbracket,prsrhlpr_t::e_hold)
22432  )
22433  {
22434  expression = parse_string_range_statement(expression);
22435  }
22436  }
22437 
22438  template <typename Allocator1,
22439  typename Allocator2,
22440  template <typename,typename> class Sequence>
22441  inline expression_node_ptr simplify(Sequence<expression_node_ptr,Allocator1>& expression_list,
22442  Sequence<bool,Allocator2>& side_effect_list,
22443  const bool specialise_on_final_type = false)
22444  {
22445  if (expression_list.empty())
22446  return error_node();
22447  else if (1 == expression_list.size())
22448  return expression_list[0];
22449 
22450  Sequence<expression_node_ptr,Allocator1> tmp_expression_list;
22451 
22452  bool return_node_present = false;
22453 
22454  for (std::size_t i = 0; i < (expression_list.size() - 1); ++i)
22455  {
22456  if (is_variable_node(expression_list[i]))
22457  continue;
22458  else if (
22459  is_return_node (expression_list[i]) ||
22460  is_break_node (expression_list[i]) ||
22461  is_continue_node(expression_list[i])
22462  )
22463  {
22464  tmp_expression_list.push_back(expression_list[i]);
22465 
22466  // Remove all subexpressions after first short-circuit
22467  // node has been encountered.
22468 
22469  for (std::size_t j = i + 1; j < expression_list.size(); ++j)
22470  {
22471  free_node(node_allocator_,expression_list[j]);
22472  }
22473 
22474  return_node_present = true;
22475 
22476  break;
22477  }
22478  else if (
22479  is_constant_node(expression_list[i]) ||
22480  is_null_node (expression_list[i]) ||
22481  !side_effect_list[i]
22482  )
22483  {
22484  free_node(node_allocator_,expression_list[i]);
22485  continue;
22486  }
22487  else
22488  tmp_expression_list.push_back(expression_list[i]);
22489  }
22490 
22491  if (!return_node_present)
22492  {
22493  tmp_expression_list.push_back(expression_list.back());
22494  }
22495 
22496  expression_list.swap(tmp_expression_list);
22497 
22498  if (tmp_expression_list.size() > expression_list.size())
22499  {
22500  exprtk_debug(("simplify() - Reduced subexpressions from %d to %d\n",
22501  static_cast<int>(tmp_expression_list.size()),
22502  static_cast<int>(expression_list .size())));
22503  }
22504 
22505  if (
22506  return_node_present ||
22507  side_effect_list.back() ||
22508  (expression_list.size() > 1)
22509  )
22510  state_.activate_side_effect("simplify()");
22511 
22512  if (1 == expression_list.size())
22513  return expression_list[0];
22514  else if (specialise_on_final_type && is_generally_string_node(expression_list.back()))
22515  return expression_generator_.vararg_function(details::e_smulti,expression_list);
22516  else
22517  return expression_generator_.vararg_function(details::e_multi,expression_list);
22518  }
22519 
22520  inline expression_node_ptr parse_multi_sequence(const std::string& source = "")
22521  {
22522  token_t::token_type close_bracket = token_t::e_rcrlbracket;
22523  token_t::token_type seperator = token_t::e_eof;
22524 
22525  if (!token_is(token_t::e_lcrlbracket))
22526  {
22527  if (token_is(token_t::e_lbracket))
22528  {
22529  close_bracket = token_t::e_rbracket;
22530  seperator = token_t::e_comma;
22531  }
22532  else
22533  {
22534  set_error(
22536  current_token(),
22537  "ERR093 - Expected '" + token_t::to_str(close_bracket) + "' for call to multi-sequence" +
22538  ((!source.empty()) ? std::string(" section of " + source): ""),
22540 
22541  return error_node();
22542  }
22543  }
22544  else if (token_is(token_t::e_rcrlbracket))
22545  {
22546  return node_allocator_.allocate<details::null_node<T> >();
22547  }
22548 
22549  std::vector<expression_node_ptr> arg_list;
22550  std::vector<bool> side_effect_list;
22551 
22552  expression_node_ptr result = error_node();
22553 
22554  scoped_vec_delete<expression_node_t> sdd((*this),arg_list);
22555 
22556  scope_handler sh(*this);
22557 
22558  scoped_bool_or_restorer sbr(state_.side_effect_present);
22559 
22560  for ( ; ; )
22561  {
22562  state_.side_effect_present = false;
22563 
22564  expression_node_ptr arg = parse_expression();
22565 
22566  if (0 == arg)
22567  return error_node();
22568  else
22569  {
22570  arg_list.push_back(arg);
22571  side_effect_list.push_back(state_.side_effect_present);
22572  }
22573 
22574  if (token_is(close_bracket))
22575  break;
22576 
22577  bool is_next_close = peek_token_is(close_bracket);
22578 
22579  if (!token_is(seperator) && is_next_close)
22580  {
22581  set_error(
22583  current_token(),
22584  "ERR094 - Expected '" + details::to_str(seperator) + "' for call to multi-sequence section of " + source,
22586 
22587  return error_node();
22588  }
22589 
22590  if (token_is(close_bracket))
22591  break;
22592  }
22593 
22594  result = simplify(arg_list,side_effect_list,source.empty());
22595 
22596  sdd.delete_ptr = (0 == result);
22597  return result;
22598  }
22599 
22600  inline bool parse_range(range_t& rp, const bool skip_lsqr = false)
22601  {
22602  // Examples of valid ranges:
22603  // 1. [1:5] -> 1..5
22604  // 2. [ :5] -> 0..5
22605  // 3. [1: ] -> 1..end
22606  // 4. [x:y] -> x..y where x <= y
22607  // 5. [x+1:y/2] -> x+1..y/2 where x+1 <= y/2
22608  // 6. [ :y] -> 0..y where 0 <= y
22609  // 7. [x: ] -> x..end where x <= end
22610 
22611  rp.clear();
22612 
22613  if (!skip_lsqr && !token_is(token_t::e_lsqrbracket))
22614  {
22615  set_error(
22617  current_token(),
22618  "ERR095 - Expected '[' for start of range",
22620 
22621  return false;
22622  }
22623 
22624  if (token_is(token_t::e_colon))
22625  {
22626  rp.n0_c.first = true;
22627  rp.n0_c.second = 0;
22628  rp.cache.first = 0;
22629  }
22630  else
22631  {
22632  expression_node_ptr r0 = parse_expression();
22633 
22634  if (0 == r0)
22635  {
22636  set_error(
22638  current_token(),
22639  "ERR096 - Failed parse begin section of range",
22641 
22642  return false;
22643  }
22644  else if (is_constant_node(r0))
22645  {
22646  const T r0_value = r0->value();
22647 
22648  if (r0_value >= T(0))
22649  {
22650  rp.n0_c.first = true;
22651  rp.n0_c.second = static_cast<std::size_t>(details::numeric::to_int64(r0_value));
22652  rp.cache.first = rp.n0_c.second;
22653  }
22654 
22655  free_node(node_allocator_,r0);
22656 
22657  if (r0_value < T(0))
22658  {
22659  set_error(
22661  current_token(),
22662  "ERR097 - Range lower bound less than zero! Constraint: r0 >= 0",
22664 
22665  return false;
22666  }
22667  }
22668  else
22669  {
22670  rp.n0_e.first = true;
22671  rp.n0_e.second = r0;
22672  }
22673 
22674  if (!token_is(token_t::e_colon))
22675  {
22676  set_error(
22678  current_token(),
22679  "ERR098 - Expected ':' for break in range",
22681 
22682  rp.free();
22683 
22684  return false;
22685  }
22686  }
22687 
22688  if (token_is(token_t::e_rsqrbracket))
22689  {
22690  rp.n1_c.first = true;
22692  }
22693  else
22694  {
22695  expression_node_ptr r1 = parse_expression();
22696 
22697  if (0 == r1)
22698  {
22699  set_error(
22701  current_token(),
22702  "ERR099 - Failed parse end section of range",
22704 
22705  rp.free();
22706 
22707  return false;
22708  }
22709  else if (is_constant_node(r1))
22710  {
22711  const T r1_value = r1->value();
22712 
22713  if (r1_value >= T(0))
22714  {
22715  rp.n1_c.first = true;
22716  rp.n1_c.second = static_cast<std::size_t>(details::numeric::to_int64(r1_value));
22717  rp.cache.second = rp.n1_c.second;
22718  }
22719 
22720  free_node(node_allocator_,r1);
22721 
22722  if (r1_value < T(0))
22723  {
22724  set_error(
22726  current_token(),
22727  "ERR100 - Range upper bound less than zero! Constraint: r1 >= 0",
22729 
22730  return false;
22731  }
22732  }
22733  else
22734  {
22735  rp.n1_e.first = true;
22736  rp.n1_e.second = r1;
22737  }
22738 
22739  if (!token_is(token_t::e_rsqrbracket))
22740  {
22741  set_error(
22743  current_token(),
22744  "ERR101 - Expected ']' for start of range",
22746 
22747  rp.free();
22748 
22749  return false;
22750  }
22751  }
22752 
22753  if (rp.const_range())
22754  {
22755  std::size_t r0 = 0;
22756  std::size_t r1 = 0;
22757 
22758  const bool rp_result = rp(r0,r1);
22759 
22760  if (!rp_result || (r0 > r1))
22761  {
22762  set_error(
22764  current_token(),
22765  "ERR102 - Invalid range, Constraint: r0 <= r1",
22767 
22768  return false;
22769  }
22770  }
22771 
22772  return true;
22773  }
22774 
22775  inline void lodge_symbol(const std::string& symbol,
22776  const symbol_type st)
22777  {
22778  dec_.add_symbol(symbol,st);
22779  }
22780 
22781  #ifndef exprtk_disable_string_capabilities
22783  {
22784  const std::string symbol = current_token().value;
22785 
22786  typedef details::stringvar_node<T>* strvar_node_t;
22787 
22788  expression_node_ptr result = error_node();
22789  strvar_node_t const_str_node = static_cast<strvar_node_t>(0);
22790 
22791  scope_element& se = sem_.get_active_element(symbol);
22792 
22793  if (scope_element::e_string == se.type)
22794  {
22795  se.active = true;
22796  result = se.str_node;
22797  lodge_symbol(symbol,e_st_local_string);
22798  }
22799  else
22800  {
22801  if (!symtab_store_.is_conststr_stringvar(symbol))
22802  {
22803  set_error(
22805  current_token(),
22806  "ERR103 - Unknown string symbol",
22808 
22809  return error_node();
22810  }
22811 
22812  result = symtab_store_.get_stringvar(symbol);
22813 
22814  if (symtab_store_.is_constant_string(symbol))
22815  {
22816  const_str_node = static_cast<strvar_node_t>(result);
22817  result = expression_generator_(const_str_node->str());
22818  }
22819 
22820  lodge_symbol(symbol,e_st_string);
22821  }
22822 
22823  if (peek_token_is(token_t::e_lsqrbracket))
22824  {
22825  next_token();
22826 
22827  if (peek_token_is(token_t::e_rsqrbracket))
22828  {
22829  next_token();
22830  next_token();
22831 
22832  if (const_str_node)
22833  {
22834  free_node(node_allocator_,result);
22835 
22836  return expression_generator_(T(const_str_node->size()));
22837  }
22838  else
22839  return node_allocator_.allocate<details::stringvar_size_node<T> >
22840  (static_cast<details::stringvar_node<T>*>(result)->ref());
22841  }
22842 
22843  range_t rp;
22844 
22845  if (!parse_range(rp))
22846  {
22847  free_node(node_allocator_,result);
22848 
22849  return error_node();
22850  }
22851  else if (const_str_node)
22852  {
22853  free_node(node_allocator_,result);
22854  result = expression_generator_(const_str_node->ref(),rp);
22855  }
22856  else
22857  result = expression_generator_(static_cast<details::stringvar_node<T>*>
22858  (result)->ref(), rp);
22859 
22860  if (result)
22861  rp.clear();
22862  }
22863  else
22864  next_token();
22865 
22866  return result;
22867  }
22868  #else
22869  inline expression_node_ptr parse_string()
22870  {
22871  return error_node();
22872  }
22873  #endif
22874 
22875  #ifndef exprtk_disable_string_capabilities
22877  {
22878  const std::string const_str = current_token().value;
22879  expression_node_ptr result = expression_generator_(const_str);
22880 
22881  if (peek_token_is(token_t::e_lsqrbracket))
22882  {
22883  next_token();
22884 
22885  if (peek_token_is(token_t::e_rsqrbracket))
22886  {
22887  next_token();
22888  next_token();
22889 
22890  free_node(node_allocator_,result);
22891 
22892  return expression_generator_(T(const_str.size()));
22893  }
22894 
22895  range_t rp;
22896 
22897  if (!parse_range(rp))
22898  {
22899  free_node(node_allocator_,result);
22900 
22901  return error_node();
22902  }
22903 
22904  free_node(node_allocator_,result);
22905 
22906  if (rp.n1_c.first && (rp.n1_c.second == std::numeric_limits<std::size_t>::max()))
22907  {
22908  rp.n1_c.second = const_str.size() - 1;
22909  rp.cache.second = rp.n1_c.second;
22910  }
22911 
22912  if (
22913  (rp.n0_c.first && (rp.n0_c.second >= const_str.size())) ||
22914  (rp.n1_c.first && (rp.n1_c.second >= const_str.size()))
22915  )
22916  {
22917  set_error(
22919  current_token(),
22920  "ERR104 - Overflow in range for string: '" + const_str + "'[" +
22921  (rp.n0_c.first ? details::to_str(static_cast<int>(rp.n0_c.second)) : "?") + ":" +
22922  (rp.n1_c.first ? details::to_str(static_cast<int>(rp.n1_c.second)) : "?") + "]",
22924 
22925  return error_node();
22926  }
22927 
22928  result = expression_generator_(const_str,rp);
22929 
22930  if (result)
22931  rp.clear();
22932  }
22933  else
22934  next_token();
22935 
22936  return result;
22937  }
22938  #else
22939  inline expression_node_ptr parse_const_string()
22940  {
22941  return error_node();
22942  }
22943  #endif
22944 
22946  {
22947  const std::string symbol = current_token().value;
22948 
22949  vector_holder_ptr vec = vector_holder_ptr(0);
22950 
22951  const scope_element& se = sem_.get_active_element(symbol);
22952 
22953  if (
22954  !details::imatch(se.name, symbol) ||
22955  (se.depth > state_.scope_depth) ||
22956  (scope_element::e_vector != se.type)
22957  )
22958  {
22959  if (0 == (vec = symtab_store_.get_vector(symbol)))
22960  {
22961  set_error(
22963  current_token(),
22964  "ERR105 - Symbol '" + symbol+ " not a vector",
22966 
22967  return error_node();
22968  }
22969  }
22970  else
22971  vec = se.vec_node;
22972 
22973  expression_node_ptr index_expr = error_node();
22974 
22975  next_token();
22976 
22977  if (!token_is(token_t::e_lsqrbracket))
22978  {
22979  return node_allocator_.allocate<vector_node_t>(vec);
22980  }
22981  else if (token_is(token_t::e_rsqrbracket))
22982  {
22983  return expression_generator_(T(vec->size()));
22984  }
22985  else if (0 == (index_expr = parse_expression()))
22986  {
22987  set_error(
22989  current_token(),
22990  "ERR106 - Failed to parse index for vector: '" + symbol + "'",
22992 
22993  return error_node();
22994  }
22995  else if (!token_is(token_t::e_rsqrbracket))
22996  {
22997  set_error(
22999  current_token(),
23000  "ERR107 - Expected ']' for index of vector: '" + symbol + "'",
23002 
23003  free_node(node_allocator_,index_expr);
23004 
23005  return error_node();
23006  }
23007 
23008  // Perform compile-time range check
23009  if (details::is_constant_node(index_expr))
23010  {
23011  const std::size_t index = static_cast<std::size_t>(details::numeric::to_int32(index_expr->value()));
23012  const std::size_t vec_size = vec->size();
23013 
23014  if (index >= vec_size)
23015  {
23016  set_error(
23018  current_token(),
23019  "ERR108 - Index of " + details::to_str(index) + " out of range for "
23020  "vector '" + symbol + "' of size " + details::to_str(vec_size),
23022 
23023  free_node(node_allocator_,index_expr);
23024 
23025  return error_node();
23026  }
23027  }
23028 
23029  return expression_generator_.vector_element(symbol,vec,index_expr);
23030  }
23031 
23032  inline expression_node_ptr parse_vararg_function_call(ivararg_function<T>* vararg_function, const std::string& vararg_function_name)
23033  {
23034  std::vector<expression_node_ptr> arg_list;
23035 
23036  expression_node_ptr result = error_node();
23037 
23038  scoped_vec_delete<expression_node_t> sdd((*this),arg_list);
23039 
23040  next_token();
23041 
23042  if (token_is(token_t::e_lbracket))
23043  {
23044  if (token_is(token_t::e_rbracket))
23045  {
23046  if (!vararg_function->allow_zero_parameters())
23047  {
23048  set_error(
23050  current_token(),
23051  "ERR109 - Zero parameter call to vararg function: "
23052  + vararg_function_name + " not allowed",
23054 
23055  return error_node();
23056  }
23057  }
23058  else
23059  {
23060  for ( ; ; )
23061  {
23062  expression_node_ptr arg = parse_expression();
23063 
23064  if (0 == arg)
23065  return error_node();
23066  else
23067  arg_list.push_back(arg);
23068 
23069  if (token_is(token_t::e_rbracket))
23070  break;
23071  else if (!token_is(token_t::e_comma))
23072  {
23073  set_error(
23075  current_token(),
23076  "ERR110 - Expected ',' for call to vararg function: "
23077  + vararg_function_name,
23079 
23080  return error_node();
23081  }
23082  }
23083  }
23084  }
23085  else if (!vararg_function->allow_zero_parameters())
23086  {
23087  set_error(
23089  current_token(),
23090  "ERR111 - Zero parameter call to vararg function: "
23091  + vararg_function_name + " not allowed",
23093 
23094  return error_node();
23095  }
23096 
23097  if (arg_list.size() < vararg_function->min_num_args())
23098  {
23099  set_error(
23101  current_token(),
23102  "ERR112 - Invalid number of parameters to call to vararg function: "
23103  + vararg_function_name + ", require at least "
23104  + details::to_str(static_cast<int>(vararg_function->min_num_args())) + " parameters",
23106 
23107  return error_node();
23108  }
23109  else if (arg_list.size() > vararg_function->max_num_args())
23110  {
23111  set_error(
23113  current_token(),
23114  "ERR113 - Invalid number of parameters to call to vararg function: "
23115  + vararg_function_name + ", require no more than "
23116  + details::to_str(static_cast<int>(vararg_function->max_num_args())) + " parameters",
23118 
23119  return error_node();
23120  }
23121 
23122  result = expression_generator_.vararg_function_call(vararg_function,arg_list);
23123 
23124  sdd.delete_ptr = (0 == result);
23125 
23126  return result;
23127  }
23128 
23130  {
23131  public:
23132 
23134  typedef std::vector<std::string> param_seq_list_t;
23135 
23137  const std::string& func_name,
23138  const std::string& param_seq)
23139  : invalid_state_(true),
23140  parser_(p),
23141  function_name_(func_name)
23142  {
23143  split(param_seq);
23144  }
23145 
23146  bool verify(const std::string& param_seq, std::size_t& pseq_index)
23147  {
23148  if (param_seq_list_.empty())
23149  return true;
23150 
23151  std::vector<std::pair<std::size_t,char> > error_list;
23152 
23153  for (std::size_t i = 0; i < param_seq_list_.size(); ++i)
23154  {
23155  details::char_t diff_value = 0;
23156  std::size_t diff_index = 0;
23157 
23158  bool result = details::sequence_match(param_seq_list_[i],
23159  param_seq,
23160  diff_index,diff_value);
23161 
23162  if (result)
23163  {
23164  pseq_index = i;
23165  return true;
23166  }
23167  else
23168  error_list.push_back(std::make_pair(diff_index,diff_value));
23169  }
23170 
23171  if (1 == error_list.size())
23172  {
23173  parser_.
23174  set_error(
23176  parser_.current_token(),
23177  "ERR114 - Failed parameter type check for function '" + function_name_ + "', "
23178  "Expected '" + param_seq_list_[0] + "' call set: '" + param_seq +"'",
23180  }
23181  else
23182  {
23183  // find first with largest diff_index;
23184  std::size_t max_diff_index = 0;
23185 
23186  for (std::size_t i = 1; i < error_list.size(); ++i)
23187  {
23188  if (error_list[i].first > error_list[max_diff_index].first)
23189  {
23190  max_diff_index = i;
23191  }
23192  }
23193 
23194  parser_.
23195  set_error(
23197  parser_.current_token(),
23198  "ERR115 - Failed parameter type check for function '" + function_name_ + "', "
23199  "Best match: '" + param_seq_list_[max_diff_index] + "' call set: '" + param_seq +"'",
23201  }
23202 
23203  return false;
23204  }
23205 
23206  std::size_t paramseq_count() const
23207  {
23208  return param_seq_list_.size();
23209  }
23210 
23211  std::string paramseq(const std::size_t& index) const
23212  {
23213  return param_seq_list_[index];
23214  }
23215 
23216  bool invalid() const
23217  {
23218  return !invalid_state_;
23219  }
23220 
23222  {
23223  return
23224  param_seq_list_.end() != std::find(param_seq_list_.begin(),
23225  param_seq_list_.end(),
23226  "Z");
23227  }
23228 
23229  private:
23230 
23231  void split(const std::string& s)
23232  {
23233  if (s.empty())
23234  return;
23235 
23236  std::size_t start = 0;
23237  std::size_t end = 0;
23238 
23239  param_seq_list_t param_seq_list;
23240 
23241  struct token_validator
23242  {
23243  static inline bool process(const std::string& str,
23244  std::size_t s, std::size_t e,
23245  param_seq_list_t& psl)
23246  {
23247  if (
23248  (e - s) &&
23249  (std::string::npos == str.find("?*")) &&
23250  (std::string::npos == str.find("**"))
23251  )
23252  {
23253  const std::string curr_str = str.substr(s, e - s);
23254 
23255  if ("Z" == curr_str)
23256  {
23257  psl.push_back(curr_str);
23258  return true;
23259  }
23260  else if (std::string::npos == curr_str.find_first_not_of("STV*?|"))
23261  {
23262  psl.push_back(curr_str);
23263  return true;
23264  }
23265  }
23266 
23267  return false;
23268  }
23269  };
23270 
23271  while (std::string::npos != (end = s.find('|',start)))
23272  {
23273  if (!token_validator::process(s, start, end, param_seq_list))
23274  {
23275  invalid_state_ = false;
23276 
23277  const std::string err_param_seq = s.substr(start, end - start);
23278 
23279  parser_.
23280  set_error(
23282  parser_.current_token(),
23283  "ERR116 - Invalid parameter sequence of '" + err_param_seq +
23284  "' for function: " + function_name_,
23286 
23287  return;
23288  }
23289  else
23290  start = end + 1;
23291  }
23292 
23293  if (start < s.size())
23294  {
23295  if (token_validator::process(s, start, s.size(), param_seq_list))
23296  param_seq_list_ = param_seq_list;
23297  else
23298  {
23299  const std::string err_param_seq = s.substr(start, s.size() - start);
23300 
23301  parser_.
23302  set_error(
23304  parser_.current_token(),
23305  "ERR117 - Invalid parameter sequence of '" + err_param_seq +
23306  "' for function: " + function_name_,
23308  return;
23309  }
23310  }
23311  }
23312 
23313  type_checker(const type_checker&);
23314  type_checker& operator=(const type_checker&);
23315 
23318  std::string function_name_;
23320  };
23321 
23322  inline expression_node_ptr parse_generic_function_call(igeneric_function<T>* function, const std::string& function_name)
23323  {
23324  std::vector<expression_node_ptr> arg_list;
23325 
23326  scoped_vec_delete<expression_node_t> sdd((*this),arg_list);
23327 
23328  next_token();
23329 
23330  std::string param_type_list;
23331 
23332  type_checker tc((*this), function_name, function->parameter_sequence);
23333 
23334  if (tc.invalid())
23335  {
23336  set_error(
23338  current_token(),
23339  "ERR118 - Type checker instantiation failure for generic function: " + function_name,
23341 
23342  return error_node();
23343  }
23344 
23345  if (
23346  !function->parameter_sequence.empty() &&
23347  function->allow_zero_parameters () &&
23348  !tc .allow_zero_parameters ()
23349  )
23350  {
23351  set_error(
23353  current_token(),
23354  "ERR119 - Mismatch in zero parameter condition for generic function: "
23355  + function_name,
23357 
23358  return error_node();
23359  }
23360 
23361  if (token_is(token_t::e_lbracket))
23362  {
23363  if (token_is(token_t::e_rbracket))
23364  {
23365  if (
23366  !function->allow_zero_parameters() &&
23367  !tc .allow_zero_parameters()
23368  )
23369  {
23370  set_error(
23372  current_token(),
23373  "ERR120 - Zero parameter call to generic function: "
23374  + function_name + " not allowed",
23376 
23377  return error_node();
23378  }
23379  }
23380  else
23381  {
23382  for ( ; ; )
23383  {
23384  expression_node_ptr arg = parse_expression();
23385 
23386  if (0 == arg)
23387  return error_node();
23388 
23389  if (is_ivector_node(arg))
23390  param_type_list += 'V';
23391  else if (is_generally_string_node(arg))
23392  param_type_list += 'S';
23393  else // Everything else is assumed to be a scalar returning expression
23394  param_type_list += 'T';
23395 
23396  arg_list.push_back(arg);
23397 
23398  if (token_is(token_t::e_rbracket))
23399  break;
23400  else if (!token_is(token_t::e_comma))
23401  {
23402  set_error(
23404  current_token(),
23405  "ERR121 - Expected ',' for call to generic function: " + function_name,
23407 
23408  return error_node();
23409  }
23410  }
23411  }
23412  }
23413  else if (
23414  !function->parameter_sequence.empty() &&
23415  function->allow_zero_parameters () &&
23416  !tc .allow_zero_parameters ()
23417  )
23418  {
23419  set_error(
23421  current_token(),
23422  "ERR122 - Zero parameter call to generic function: "
23423  + function_name + " not allowed",
23425 
23426  return error_node();
23427  }
23428 
23429  std::size_t param_seq_index = 0;
23430 
23431  if (
23432  state_.type_check_enabled &&
23433  !tc.verify(param_type_list, param_seq_index)
23434  )
23435  {
23436  set_error(
23438  current_token(),
23439  "ERR123 - Expected ',' for call to generic function: " + function_name,
23441 
23442  return error_node();
23443  }
23444 
23445  expression_node_ptr result = error_node();
23446 
23447  if (tc.paramseq_count() <= 1)
23448  result = expression_generator_
23449  .generic_function_call(function, arg_list);
23450  else
23451  result = expression_generator_
23452  .generic_function_call(function, arg_list, param_seq_index);
23453 
23454  sdd.delete_ptr = (0 == result);
23455 
23456  return result;
23457  }
23458 
23459  #ifndef exprtk_disable_string_capabilities
23460  inline expression_node_ptr parse_string_function_call(igeneric_function<T>* function, const std::string& function_name)
23461  {
23462  std::vector<expression_node_ptr> arg_list;
23463 
23464  scoped_vec_delete<expression_node_t> sdd((*this),arg_list);
23465 
23466  next_token();
23467 
23468  std::string param_type_list;
23469 
23470  type_checker tc((*this), function_name, function->parameter_sequence);
23471 
23472  if (
23473  (!function->parameter_sequence.empty()) &&
23474  (0 == tc.paramseq_count())
23475  )
23476  {
23477  return error_node();
23478  }
23479 
23480  if (token_is(token_t::e_lbracket))
23481  {
23482  if (!token_is(token_t::e_rbracket))
23483  {
23484  for ( ; ; )
23485  {
23486  expression_node_ptr arg = parse_expression();
23487 
23488  if (0 == arg)
23489  return error_node();
23490 
23491  if (is_ivector_node(arg))
23492  param_type_list += 'V';
23493  else if (is_generally_string_node(arg))
23494  param_type_list += 'S';
23495  else // Everything else is a scalar returning expression
23496  param_type_list += 'T';
23497 
23498  arg_list.push_back(arg);
23499 
23500  if (token_is(token_t::e_rbracket))
23501  break;
23502  else if (!token_is(token_t::e_comma))
23503  {
23504  set_error(
23506  current_token(),
23507  "ERR124 - Expected ',' for call to string function: " + function_name,
23509 
23510  return error_node();
23511  }
23512  }
23513  }
23514  }
23515 
23516  std::size_t param_seq_index = 0;
23517 
23518  if (!tc.verify(param_type_list, param_seq_index))
23519  {
23520  set_error(
23522  current_token(),
23523  "ERR125 - Expected ',' for call to string function: " + function_name,
23525 
23526  return error_node();
23527  }
23528 
23529  expression_node_ptr result = error_node();
23530 
23531  if (tc.paramseq_count() <= 1)
23532  result = expression_generator_
23533  .string_function_call(function, arg_list);
23534  else
23535  result = expression_generator_
23536  .string_function_call(function, arg_list, param_seq_index);
23537 
23538  sdd.delete_ptr = (0 == result);
23539 
23540  return result;
23541  }
23542  #endif
23543 
23544  template <typename Type, std::size_t NumberOfParameters>
23546  {
23547  static inline expression_node_ptr process(parser<Type>& p,const details::operator_type opt_type, const std::string& sf_name)
23548  {
23549  expression_node_ptr branch[NumberOfParameters];
23550  expression_node_ptr result = error_node();
23551 
23552  std::fill_n(branch,NumberOfParameters,reinterpret_cast<expression_node_ptr>(0));
23553 
23555 
23556  p.next_token();
23557 
23558  if (!p.token_is(token_t::e_lbracket))
23559  {
23560  p.set_error(
23562  p.current_token(),
23563  "ERR126 - Expected '(' for special function '" + sf_name + "'",
23565 
23566  return error_node();
23567  }
23568 
23569  for (std::size_t i = 0; i < NumberOfParameters; ++i)
23570  {
23571  branch[i] = p.parse_expression();
23572 
23573  if (0 == branch[i])
23574  {
23575  return p.error_node();
23576  }
23577  else if (i < (NumberOfParameters - 1))
23578  {
23579  if (!p.token_is(token_t::e_comma))
23580  {
23581  p.set_error(
23583  p.current_token(),
23584  "ERR127 - Expected ',' before next parameter of special function '" + sf_name + "'",
23586 
23587  return p.error_node();
23588  }
23589  }
23590  }
23591 
23592  if (!p.token_is(token_t::e_rbracket))
23593  {
23594  p.set_error(
23596  p.current_token(),
23597  "ERR128 - Invalid number of parameters for special function '" + sf_name + "'",
23599 
23600  return p.error_node();
23601  }
23602  else
23603  result = p.expression_generator_.special_function(opt_type,branch);
23604 
23605  sd.delete_ptr = (0 == result);
23606 
23607  return result;
23608  }
23609  };
23610 
23612  {
23613  const std::string sf_name = current_token().value;
23614 
23615  // Expect: $fDD(expr0,expr1,expr2) or $fDD(expr0,expr1,expr2,expr3)
23616  if (
23617  !details::is_digit(sf_name[2]) ||
23618  !details::is_digit(sf_name[3])
23619  )
23620  {
23621  set_error(
23623  current_token(),
23624  "ERR129 - Invalid special function[1]: " + sf_name,
23626 
23627  return error_node();
23628  }
23629 
23630  const int id = (sf_name[2] - '0') * 10 +
23631  (sf_name[3] - '0');
23632 
23633  if (id >= details::e_sffinal)
23634  {
23635  set_error(
23637  current_token(),
23638  "ERR130 - Invalid special function[2]: " + sf_name,
23640 
23641  return error_node();
23642  }
23643 
23644  const int sf_3_to_4 = details::e_sf48;
23645  const details::operator_type opt_type = details::operator_type(id + 1000);
23646  const std::size_t NumberOfParameters = (id < (sf_3_to_4 - 1000)) ? 3U : 4U;
23647 
23648  switch (NumberOfParameters)
23649  {
23650  case 3 : return parse_special_function_impl<T,3>::process((*this), opt_type, sf_name);
23651  case 4 : return parse_special_function_impl<T,4>::process((*this), opt_type, sf_name);
23652  default : return error_node();
23653  }
23654  }
23655 
23657  {
23658  next_token();
23659  return node_allocator_.allocate<details::null_node<T> >();
23660  }
23661 
23662  #ifndef exprtk_disable_break_continue
23664  {
23665  if (state_.parsing_break_stmt)
23666  {
23667  set_error(
23669  current_token(),
23670  "ERR131 - Break call within a break call is not allowed",
23672 
23673  return error_node();
23674  }
23675 
23676  scoped_bool_negator sbn(state_.parsing_break_stmt);
23677 
23678  if (!brkcnt_list_.empty())
23679  {
23680  next_token();
23681 
23682  brkcnt_list_.front() = true;
23683 
23684  expression_node_ptr return_expr = error_node();
23685 
23686  if (token_is(token_t::e_lsqrbracket))
23687  {
23688  if (0 == (return_expr = parse_expression()))
23689  {
23690  set_error(
23692  current_token(),
23693  "ERR132 - Failed to parse return expression for 'break' statement",
23695 
23696  return error_node();
23697  }
23698  else if (!token_is(token_t::e_rsqrbracket))
23699  {
23700  set_error(
23702  current_token(),
23703  "ERR133 - Expected ']' at the completion of break's return expression",
23705 
23706  free_node(node_allocator_,return_expr);
23707 
23708  return error_node();
23709  }
23710  }
23711 
23712  state_.activate_side_effect("parse_break_statement()");
23713 
23714  return node_allocator_.allocate<details::break_node<T> >(return_expr);
23715  }
23716  else
23717  {
23718  set_error(
23720  current_token(),
23721  "ERR134 - Invalid use of 'break', allowed only in the scope of a loop",
23723  }
23724 
23725  return error_node();
23726  }
23727 
23729  {
23730  if (!brkcnt_list_.empty())
23731  {
23732  next_token();
23733 
23734  brkcnt_list_.front() = true;
23735  state_.activate_side_effect("parse_continue_statement()");
23736 
23737  return node_allocator_.allocate<details::continue_node<T> >();
23738  }
23739  else
23740  {
23741  set_error(
23743  current_token(),
23744  "ERR135 - Invalid use of 'continue', allowed only in the scope of a loop",
23746 
23747  return error_node();
23748  }
23749  }
23750  #endif
23751 
23752  inline expression_node_ptr parse_define_vector_statement(const std::string& vec_name)
23753  {
23754  expression_node_ptr size_expr = error_node();
23755 
23756  if (!token_is(token_t::e_lsqrbracket))
23757  {
23758  set_error(
23760  current_token(),
23761  "ERR136 - Expected '[' as part of vector size definition",
23763 
23764  return error_node();
23765  }
23766  else if (0 == (size_expr = parse_expression()))
23767  {
23768  set_error(
23770  current_token(),
23771  "ERR137 - Failed to determine size of vector '" + vec_name + "'",
23773 
23774  return error_node();
23775  }
23776  else if (!is_constant_node(size_expr))
23777  {
23778  free_node(node_allocator_,size_expr);
23779 
23780  set_error(
23782  current_token(),
23783  "ERR138 - Expected a literal number as size of vector '" + vec_name + "'",
23785 
23786  return error_node();
23787  }
23788 
23789  T vector_size = size_expr->value();
23790 
23791  free_node(node_allocator_,size_expr);
23792 
23793  if (
23794  (vector_size <= T(0)) ||
23795  std::not_equal_to<T>()
23796  (T(0),vector_size - details::numeric::trunc(vector_size))
23797  )
23798  {
23799  set_error(
23801  current_token(),
23802  "ERR139 - Invalid vector size. Must be an integer greater than zero, size: " +
23805 
23806  return error_node();
23807  }
23808 
23809  std::vector<expression_node_ptr> vec_initilizer_list;
23810 
23811  scoped_vec_delete<expression_node_t> svd((*this),vec_initilizer_list);
23812 
23813  bool single_value_initialiser = false;
23814  bool vec_to_vec_initialiser = false;
23815  bool null_initialisation = false;
23816 
23817  if (!token_is(token_t::e_rsqrbracket))
23818  {
23819  set_error(
23821  current_token(),
23822  "ERR140 - Expected ']' as part of vector size definition",
23824 
23825  return error_node();
23826  }
23827  else if (!token_is(token_t::e_eof))
23828  {
23829  if (!token_is(token_t::e_assign))
23830  {
23831  set_error(
23833  current_token(),
23834  "ERR141 - Expected ':=' as part of vector definition",
23836 
23837  return error_node();
23838  }
23839  else if (token_is(token_t::e_lsqrbracket))
23840  {
23841  expression_node_ptr initialiser = parse_expression();
23842 
23843  if (0 == initialiser)
23844  {
23845  set_error(
23847  current_token(),
23848  "ERR142 - Failed to parse single vector initialiser",
23850 
23851  return error_node();
23852  }
23853 
23854  vec_initilizer_list.push_back(initialiser);
23855 
23856  if (!token_is(token_t::e_rsqrbracket))
23857  {
23858  set_error(
23860  current_token(),
23861  "ERR143 - Expected ']' to close single value vector initialiser",
23863 
23864  return error_node();
23865  }
23866 
23867  single_value_initialiser = true;
23868  }
23869  else if (!token_is(token_t::e_lcrlbracket))
23870  {
23871  expression_node_ptr initialiser = error_node();
23872 
23873  // Is this a vector to vector assignment and initialisation?
23874  if (token_t::e_symbol == current_token().type)
23875  {
23876  // Is it a locally defined vector?
23877  scope_element& se = sem_.get_active_element(current_token().value);
23878 
23879  if (scope_element::e_vector == se.type)
23880  {
23881  if (0 != (initialiser = parse_expression()))
23882  vec_initilizer_list.push_back(initialiser);
23883  else
23884  return error_node();
23885  }
23886  // Are we dealing with a user defined vector?
23887  else if (symtab_store_.is_vector(current_token().value))
23888  {
23889  lodge_symbol(current_token().value,e_st_vector);
23890 
23891  if (0 != (initialiser = parse_expression()))
23892  vec_initilizer_list.push_back(initialiser);
23893  else
23894  return error_node();
23895  }
23896  // Are we dealing with a null initialisation vector definition?
23897  else if (token_is(token_t::e_symbol,"null"))
23898  null_initialisation = true;
23899  }
23900 
23901  if (!null_initialisation)
23902  {
23903  if (0 == initialiser)
23904  {
23905  set_error(
23907  current_token(),
23908  "ERR144 - Expected '{' as part of vector initialiser list",
23910 
23911  return error_node();
23912  }
23913  else
23914  vec_to_vec_initialiser = true;
23915  }
23916  }
23917  else if (!token_is(token_t::e_rcrlbracket))
23918  {
23919  for ( ; ; )
23920  {
23921  expression_node_ptr initialiser = parse_expression();
23922 
23923  if (0 == initialiser)
23924  {
23925  set_error(
23927  current_token(),
23928  "ERR145 - Expected '{' as part of vector initialiser list",
23930 
23931  return error_node();
23932  }
23933  else
23934  vec_initilizer_list.push_back(initialiser);
23935 
23936  if (token_is(token_t::e_rcrlbracket))
23937  break;
23938 
23939  bool is_next_close = peek_token_is(token_t::e_rcrlbracket);
23940 
23941  if (!token_is(token_t::e_comma) && is_next_close)
23942  {
23943  set_error(
23945  current_token(),
23946  "ERR146 - Expected ',' between vector initialisers",
23948 
23949  return error_node();
23950  }
23951 
23952  if (token_is(token_t::e_rcrlbracket))
23953  break;
23954  }
23955  }
23956 
23957  if (
23958  !token_is(token_t::e_rbracket ,prsrhlpr_t::e_hold) &&
23959  !token_is(token_t::e_rcrlbracket,prsrhlpr_t::e_hold) &&
23960  !token_is(token_t::e_rsqrbracket,prsrhlpr_t::e_hold)
23961  )
23962  {
23963  if (!token_is(token_t::e_eof))
23964  {
23965  set_error(
23967  current_token(),
23968  "ERR147 - Expected ';' at end of vector definition",
23970 
23971  return error_node();
23972  }
23973  }
23974 
23975  if (vec_initilizer_list.size() > vector_size)
23976  {
23977  set_error(
23979  current_token(),
23980  "ERR148 - Initialiser list larger than the number of elements in the vector: '" + vec_name + "'",
23982 
23983  return error_node();
23984  }
23985  }
23986 
23987  typename symbol_table_t::vector_holder_ptr vec_holder = typename symbol_table_t::vector_holder_ptr(0);
23988 
23989  const std::size_t vec_size = static_cast<std::size_t>(details::numeric::to_int32(vector_size));
23990 
23991  scope_element& se = sem_.get_element(vec_name);
23992 
23993  if (se.name == vec_name)
23994  {
23995  if (se.active)
23996  {
23997  set_error(
23999  current_token(),
24000  "ERR149 - Illegal redefinition of local vector: '" + vec_name + "'",
24002 
24003  return error_node();
24004  }
24005  else if (
24006  (se.size == vec_size) &&
24007  (scope_element::e_vector == se.type)
24008  )
24009  {
24010  vec_holder = se.vec_node;
24011  se.active = true;
24012  se.depth = state_.scope_depth;
24013  se.ref_count++;
24014  }
24015  }
24016 
24017  if (0 == vec_holder)
24018  {
24019  scope_element nse;
24020  nse.name = vec_name;
24021  nse.active = true;
24022  nse.ref_count = 1;
24023  nse.type = scope_element::e_vector;
24024  nse.depth = state_.scope_depth;
24025  nse.size = vec_size;
24026  nse.data = new T[vec_size];
24027  nse.vec_node = new typename scope_element::vector_holder_t((T*)(nse.data),nse.size);
24028 
24029  if (!sem_.add_element(nse))
24030  {
24031  set_error(
24033  current_token(),
24034  "ERR150 - Failed to add new local vector '" + vec_name + "' to SEM",
24036 
24037  sem_.free_element(nse);
24038 
24039  return error_node();
24040  }
24041 
24042  vec_holder = nse.vec_node;
24043 
24044  exprtk_debug(("parse_define_vector_statement() - INFO - Added new local vector: %s[%d]\n",
24045  nse.name.c_str(),
24046  static_cast<int>(nse.size)));
24047  }
24048 
24049  state_.activate_side_effect("parse_define_vector_statement()");
24050 
24051  lodge_symbol(vec_name,e_st_local_vector);
24052 
24053  expression_node_ptr result = error_node();
24054 
24055  if (null_initialisation)
24056  result = expression_generator_(T(0.0));
24057  else if (vec_to_vec_initialiser)
24058  result = expression_generator_(
24060  node_allocator_.allocate<vector_node_t>(vec_holder),
24061  vec_initilizer_list[0]);
24062  else
24063  result = node_allocator_
24065  (*vec_holder)[0],
24066  vec_size,
24067  vec_initilizer_list,
24068  single_value_initialiser);
24069 
24070  svd.delete_ptr = (0 == result);
24071 
24072  return result;
24073  }
24074 
24075  #ifndef exprtk_disable_string_capabilities
24076  inline expression_node_ptr parse_define_string_statement(const std::string& str_name, expression_node_ptr initialisation_expression)
24077  {
24078  stringvar_node_t* str_node = reinterpret_cast<stringvar_node_t*>(0);
24079 
24080  scope_element& se = sem_.get_element(str_name);
24081 
24082  if (se.name == str_name)
24083  {
24084  if (se.active)
24085  {
24086  set_error(
24088  current_token(),
24089  "ERR151 - Illegal redefinition of local variable: '" + str_name + "'",
24091 
24092  free_node(node_allocator_,initialisation_expression);
24093 
24094  return error_node();
24095  }
24096  else if (scope_element::e_string == se.type)
24097  {
24098  str_node = se.str_node;
24099  se.active = true;
24100  se.depth = state_.scope_depth;
24101  se.ref_count++;
24102  }
24103  }
24104 
24105  if (0 == str_node)
24106  {
24107  scope_element nse;
24108  nse.name = str_name;
24109  nse.active = true;
24110  nse.ref_count = 1;
24111  nse.type = scope_element::e_string;
24112  nse.depth = state_.scope_depth;
24113  nse.data = new std::string;
24114  nse.str_node = new stringvar_node_t(*(std::string*)(nse.data));
24115 
24116  if (!sem_.add_element(nse))
24117  {
24118  set_error(
24120  current_token(),
24121  "ERR152 - Failed to add new local string variable '" + str_name + "' to SEM",
24123 
24124  free_node(node_allocator_,initialisation_expression);
24125 
24126  sem_.free_element(nse);
24127 
24128  return error_node();
24129  }
24130 
24131  str_node = nse.str_node;
24132 
24133  exprtk_debug(("parse_define_string_statement() - INFO - Added new local string variable: %s\n",nse.name.c_str()));
24134  }
24135 
24136  lodge_symbol(str_name,e_st_local_string);
24137 
24138  state_.activate_side_effect("parse_define_string_statement()");
24139 
24140  expression_node_ptr branch[2] = {0};
24141 
24142  branch[0] = str_node;
24143  branch[1] = initialisation_expression;
24144 
24145  return expression_generator_(details::e_assign,branch);
24146  }
24147  #else
24148  inline expression_node_ptr parse_define_string_statement(const std::string&, expression_node_ptr)
24149  {
24150  return error_node();
24151  }
24152  #endif
24153 
24154  inline bool local_variable_is_shadowed(const std::string& symbol)
24155  {
24156  const scope_element& se = sem_.get_element(symbol);
24157  return (se.name == symbol) && se.active;
24158  }
24159 
24161  {
24162  if (settings_.vardef_disabled())
24163  {
24164  set_error(
24166  current_token(),
24167  "ERR153 - Illegal variable definition",
24169 
24170  return error_node();
24171  }
24172  else if (!details::imatch(current_token().value,"var"))
24173  {
24174  return error_node();
24175  }
24176  else
24177  next_token();
24178 
24179  const std::string var_name = current_token().value;
24180 
24181  expression_node_ptr initialisation_expression = error_node();
24182 
24183  if (!token_is(token_t::e_symbol))
24184  {
24185  set_error(
24187  current_token(),
24188  "ERR154 - Expected a symbol for variable definition",
24190 
24191  return error_node();
24192  }
24193  else if (details::is_reserved_symbol(var_name))
24194  {
24195  set_error(
24197  current_token(),
24198  "ERR155 - Illegal redefinition of reserved keyword: '" + var_name + "'",
24200 
24201  return error_node();
24202  }
24203  else if (symtab_store_.symbol_exists(var_name))
24204  {
24205  set_error(
24207  current_token(),
24208  "ERR156 - Illegal redefinition of variable '" + var_name + "'",
24210 
24211  return error_node();
24212  }
24213  else if (local_variable_is_shadowed(var_name))
24214  {
24215  set_error(
24217  current_token(),
24218  "ERR157 - Illegal redefinition of local variable: '" + var_name + "'",
24220 
24221  return error_node();
24222  }
24223  else if (token_is(token_t::e_lsqrbracket,prsrhlpr_t::e_hold))
24224  {
24225  return parse_define_vector_statement(var_name);
24226  }
24227  else if (token_is(token_t::e_lcrlbracket,prsrhlpr_t::e_hold))
24228  {
24229  return parse_uninitialised_var_statement(var_name);
24230  }
24231  else if (token_is(token_t::e_assign))
24232  {
24233  if (0 == (initialisation_expression = parse_expression()))
24234  {
24235  set_error(
24237  current_token(),
24238  "ERR158 - Failed to parse initialisation expression",
24240 
24241  return error_node();
24242  }
24243  }
24244 
24245  if (
24246  !token_is(token_t::e_rbracket ,prsrhlpr_t::e_hold) &&
24247  !token_is(token_t::e_rcrlbracket,prsrhlpr_t::e_hold) &&
24248  !token_is(token_t::e_rsqrbracket,prsrhlpr_t::e_hold)
24249  )
24250  {
24251  if (!token_is(token_t::e_eof,prsrhlpr_t::e_hold))
24252  {
24253  set_error(
24255  current_token(),
24256  "ERR159 - Expected ';' after variable definition",
24258 
24259  free_node(node_allocator_,initialisation_expression);
24260 
24261  return error_node();
24262  }
24263  }
24264 
24265  if (
24266  (0 != initialisation_expression) &&
24267  details::is_generally_string_node(initialisation_expression)
24268  )
24269  {
24270  return parse_define_string_statement(var_name,initialisation_expression);
24271  }
24272 
24273  expression_node_ptr var_node = reinterpret_cast<expression_node_ptr>(0);
24274 
24275  scope_element& se = sem_.get_element(var_name);
24276 
24277  if (se.name == var_name)
24278  {
24279  if (se.active)
24280  {
24281  set_error(
24283  current_token(),
24284  "ERR160 - Illegal redefinition of local variable: '" + var_name + "'",
24286 
24287  free_node(node_allocator_, initialisation_expression);
24288 
24289  return error_node();
24290  }
24291  else if (scope_element::e_variable == se.type)
24292  {
24293  var_node = se.var_node;
24294  se.active = true;
24295  se.depth = state_.scope_depth;
24296  se.ref_count++;
24297  }
24298  }
24299 
24300  if (0 == var_node)
24301  {
24302  scope_element nse;
24303  nse.name = var_name;
24304  nse.active = true;
24305  nse.ref_count = 1;
24306  nse.type = scope_element::e_variable;
24307  nse.depth = state_.scope_depth;
24308  nse.data = new T(T(0));
24309  nse.var_node = node_allocator_.allocate<variable_node_t>(*(T*)(nse.data));
24310 
24311  if (!sem_.add_element(nse))
24312  {
24313  set_error(
24315  current_token(),
24316  "ERR161 - Failed to add new local variable '" + var_name + "' to SEM",
24318 
24319  free_node(node_allocator_, initialisation_expression);
24320 
24321  sem_.free_element(nse);
24322 
24323  return error_node();
24324  }
24325 
24326  var_node = nse.var_node;
24327 
24328  exprtk_debug(("parse_define_var_statement() - INFO - Added new local variable: %s\n",nse.name.c_str()));
24329  }
24330 
24331  state_.activate_side_effect("parse_define_var_statement()");
24332 
24333  lodge_symbol(var_name,e_st_local_variable);
24334 
24335  expression_node_ptr branch[2] = {0};
24336 
24337  branch[0] = var_node;
24338  branch[1] = initialisation_expression ? initialisation_expression : expression_generator_(T(0));
24339 
24340  return expression_generator_(details::e_assign,branch);
24341  }
24342 
24343  inline expression_node_ptr parse_uninitialised_var_statement(const std::string& var_name)
24344  {
24345  if (
24346  !token_is(token_t::e_lcrlbracket) ||
24347  !token_is(token_t::e_rcrlbracket)
24348  )
24349  {
24350  set_error(
24352  current_token(),
24353  "ERR162 - Expected a '{}' for uninitialised var definition",
24355 
24356  return error_node();
24357  }
24358  else if (!token_is(token_t::e_eof,prsrhlpr_t::e_hold))
24359  {
24360  set_error(
24362  current_token(),
24363  "ERR163 - Expected ';' after uninitialised variable definition",
24365 
24366  return error_node();
24367  }
24368 
24369  expression_node_ptr var_node = reinterpret_cast<expression_node_ptr>(0);
24370 
24371  scope_element& se = sem_.get_element(var_name);
24372 
24373  if (se.name == var_name)
24374  {
24375  if (se.active)
24376  {
24377  set_error(
24379  current_token(),
24380  "ERR164 - Illegal redefinition of local variable: '" + var_name + "'",
24382 
24383  return error_node();
24384  }
24385  else if (scope_element::e_variable == se.type)
24386  {
24387  var_node = se.var_node;
24388  se.active = true;
24389  se.ref_count++;
24390  }
24391  }
24392 
24393  if (0 == var_node)
24394  {
24395  scope_element nse;
24396  nse.name = var_name;
24397  nse.active = true;
24398  nse.ref_count = 1;
24399  nse.type = scope_element::e_variable;
24400  nse.depth = state_.scope_depth;
24401  nse.ip_index = sem_.next_ip_index();
24402  nse.data = new T(T(0));
24403  nse.var_node = node_allocator_.allocate<variable_node_t>(*(T*)(nse.data));
24404 
24405  if (!sem_.add_element(nse))
24406  {
24407  set_error(
24409  current_token(),
24410  "ERR165 - Failed to add new local variable '" + var_name + "' to SEM",
24412 
24413  sem_.free_element(nse);
24414 
24415  return error_node();
24416  }
24417 
24418  exprtk_debug(("parse_uninitialised_var_statement() - INFO - Added new local variable: %s\n",
24419  nse.name.c_str()));
24420  }
24421 
24422  lodge_symbol(var_name,e_st_local_variable);
24423 
24424  state_.activate_side_effect("parse_uninitialised_var_statement()");
24425 
24426  return expression_generator_(T(0));
24427  }
24428 
24430  {
24431  if (!details::imatch(current_token().value,"swap"))
24432  {
24433  return error_node();
24434  }
24435  else
24436  next_token();
24437 
24438  if (!token_is(token_t::e_lbracket))
24439  {
24440  set_error(
24442  current_token(),
24443  "ERR166 - Expected '(' at start of swap statement",
24445 
24446  return error_node();
24447  }
24448 
24449  expression_node_ptr variable0 = error_node();
24450  expression_node_ptr variable1 = error_node();
24451 
24452  bool variable0_generated = false;
24453  bool variable1_generated = false;
24454 
24455  const std::string var0_name = current_token().value;
24456 
24457  if (!token_is(token_t::e_symbol,prsrhlpr_t::e_hold))
24458  {
24459  set_error(
24461  current_token(),
24462  "ERR167 - Expected a symbol for variable or vector element definition",
24464 
24465  return error_node();
24466  }
24467  else if (peek_token_is(token_t::e_lsqrbracket))
24468  {
24469  if (0 == (variable0 = parse_vector()))
24470  {
24471  set_error(
24473  current_token(),
24474  "ERR168 - First parameter to swap is an invalid vector element: '" + var0_name + "'",
24476 
24477  return error_node();
24478  }
24479 
24480  variable0_generated = true;
24481  }
24482  else
24483  {
24484  if (symtab_store_.is_variable(var0_name))
24485  {
24486  variable0 = symtab_store_.get_variable(var0_name);
24487  }
24488 
24489  scope_element& se = sem_.get_element(var0_name);
24490 
24491  if (
24492  (se.active) &&
24493  (se.name == var0_name) &&
24494  (scope_element::e_variable == se.type)
24495  )
24496  {
24497  variable0 = se.var_node;
24498  }
24499 
24500  lodge_symbol(var0_name,e_st_variable);
24501 
24502  if (0 == variable0)
24503  {
24504  set_error(
24506  current_token(),
24507  "ERR169 - First parameter to swap is an invalid variable: '" + var0_name + "'",
24509 
24510  return error_node();
24511  }
24512  else
24513  next_token();
24514  }
24515 
24516  if (!token_is(token_t::e_comma))
24517  {
24518  set_error(
24520  current_token(),
24521  "ERR170 - Expected ',' between parameters to swap",
24523 
24524  if (variable0_generated)
24525  {
24526  free_node(node_allocator_,variable0);
24527  }
24528 
24529  return error_node();
24530  }
24531 
24532  const std::string var1_name = current_token().value;
24533 
24534  if (!token_is(token_t::e_symbol,prsrhlpr_t::e_hold))
24535  {
24536  set_error(
24538  current_token(),
24539  "ERR171 - Expected a symbol for variable or vector element definition",
24541 
24542  if (variable0_generated)
24543  {
24544  free_node(node_allocator_,variable0);
24545  }
24546 
24547  return error_node();
24548  }
24549  else if (peek_token_is(token_t::e_lsqrbracket))
24550  {
24551  if (0 == (variable1 = parse_vector()))
24552  {
24553  set_error(
24555  current_token(),
24556  "ERR172 - Second parameter to swap is an invalid vector element: '" + var1_name + "'",
24558 
24559  if (variable0_generated)
24560  {
24561  free_node(node_allocator_,variable0);
24562  }
24563 
24564  return error_node();
24565  }
24566 
24567  variable1_generated = true;
24568  }
24569  else
24570  {
24571  if (symtab_store_.is_variable(var1_name))
24572  {
24573  variable1 = symtab_store_.get_variable(var1_name);
24574  }
24575 
24576  scope_element& se = sem_.get_element(var1_name);
24577 
24578  if (
24579  (se.active) &&
24580  (se.name == var1_name) &&
24581  (scope_element::e_variable == se.type)
24582  )
24583  {
24584  variable1 = se.var_node;
24585  }
24586 
24587  lodge_symbol(var1_name,e_st_variable);
24588 
24589  if (0 == variable1)
24590  {
24591  set_error(
24593  current_token(),
24594  "ERR173 - Second parameter to swap is an invalid variable: '" + var1_name + "'",
24596 
24597  if (variable0_generated)
24598  {
24599  free_node(node_allocator_,variable0);
24600  }
24601 
24602  return error_node();
24603  }
24604  else
24605  next_token();
24606  }
24607 
24608  if (!token_is(token_t::e_rbracket))
24609  {
24610  set_error(
24612  current_token(),
24613  "ERR174 - Expected ')' at end of swap statement",
24615 
24616  if (variable0_generated)
24617  {
24618  free_node(node_allocator_,variable0);
24619  }
24620 
24621  if (variable1_generated)
24622  {
24623  free_node(node_allocator_,variable1);
24624  }
24625 
24626  return error_node();
24627  }
24628 
24629  typedef details::variable_node<T>* variable_node_ptr;
24630 
24631  variable_node_ptr v0 = variable_node_ptr(0);
24632  variable_node_ptr v1 = variable_node_ptr(0);
24633 
24634  expression_node_ptr result = error_node();
24635 
24636  if (
24637  (0 != (v0 = dynamic_cast<variable_node_ptr>(variable0))) &&
24638  (0 != (v1 = dynamic_cast<variable_node_ptr>(variable1)))
24639  )
24640  {
24641  result = node_allocator_.allocate<details::swap_node<T> >(v0, v1);
24642 
24643  if (variable0_generated)
24644  {
24645  free_node(node_allocator_,variable0);
24646  }
24647 
24648  if (variable1_generated)
24649  {
24650  free_node(node_allocator_,variable1);
24651  }
24652  }
24653  else
24654  result = node_allocator_.allocate<details::swap_generic_node<T> >
24655  (variable0, variable1);
24656 
24657  state_.activate_side_effect("parse_swap_statement()");
24658 
24659  return result;
24660  }
24661 
24662  #ifndef exprtk_disable_return_statement
24664  {
24665  if (state_.parsing_return_stmt)
24666  {
24667  set_error(
24669  current_token(),
24670  "ERR175 - Return call within a return call is not allowed",
24672 
24673  return error_node();
24674  }
24675 
24676  scoped_bool_negator sbn(state_.parsing_return_stmt);
24677 
24678  std::vector<expression_node_ptr> arg_list;
24679 
24680  scoped_vec_delete<expression_node_t> sdd((*this),arg_list);
24681 
24682  if (!details::imatch(current_token().value,"return"))
24683  {
24684  return error_node();
24685  }
24686  else
24687  next_token();
24688 
24689  if (!token_is(token_t::e_lsqrbracket))
24690  {
24691  set_error(
24693  current_token(),
24694  "ERR176 - Expected '[' at start of return statement",
24696 
24697  return error_node();
24698  }
24699  else if (!token_is(token_t::e_rsqrbracket))
24700  {
24701  for ( ; ; )
24702  {
24703  expression_node_ptr arg = parse_expression();
24704 
24705  if (0 == arg)
24706  return error_node();
24707 
24708  arg_list.push_back(arg);
24709 
24710  if (token_is(token_t::e_rsqrbracket))
24711  break;
24712  else if (!token_is(token_t::e_comma))
24713  {
24714  set_error(
24716  current_token(),
24717  "ERR177 - Expected ',' between values during call to return",
24719 
24720  return error_node();
24721  }
24722  }
24723  }
24724  else if (settings_.zero_return_disabled())
24725  {
24726  set_error(
24728  current_token(),
24729  "ERR178 - Zero parameter return statement not allowed",
24731 
24732  return error_node();
24733  }
24734 
24735  lexer::token prev_token = current_token();
24736 
24737  if (token_is(token_t::e_rsqrbracket))
24738  {
24739  if (!arg_list.empty())
24740  {
24741  set_error(
24743  prev_token,
24744  "ERR179 - Invalid ']' found during return call",
24746 
24747  return error_node();
24748  }
24749  }
24750 
24751  std::string ret_param_type_list;
24752 
24753  for (std::size_t i = 0; i < arg_list.size(); ++i)
24754  {
24755  if (0 == arg_list[i])
24756  return error_node();
24757  else if (is_ivector_node(arg_list[i]))
24758  ret_param_type_list += 'V';
24759  else if (is_generally_string_node(arg_list[i]))
24760  ret_param_type_list += 'S';
24761  else
24762  ret_param_type_list += 'T';
24763  }
24764 
24765  dec_.retparam_list_.push_back(ret_param_type_list);
24766 
24767  expression_node_ptr result = expression_generator_.return_call(arg_list);
24768 
24769  sdd.delete_ptr = (0 == result);
24770 
24771  state_.return_stmt_present = true;
24772 
24773  state_.activate_side_effect("parse_return_statement()");
24774 
24775  return result;
24776  }
24777  #else
24778  inline expression_node_ptr parse_return_statement()
24779  {
24780  return error_node();
24781  }
24782  #endif
24783 
24784  inline bool post_variable_process(const std::string& symbol)
24785  {
24786  if (
24787  peek_token_is(token_t::e_lbracket ) ||
24788  peek_token_is(token_t::e_lcrlbracket) ||
24789  peek_token_is(token_t::e_lsqrbracket)
24790  )
24791  {
24792  if (!settings_.commutative_check_enabled())
24793  {
24794  set_error(
24796  current_token(),
24797  "ERR180 - Invalid sequence of variable '"+ symbol + "' and bracket",
24799 
24800  return false;
24801  }
24802 
24803  lexer().insert_front(token_t::e_mul);
24804  }
24805 
24806  return true;
24807  }
24808 
24809  inline bool post_bracket_process(const typename token_t::token_type& token, expression_node_ptr& branch)
24810  {
24811  bool implied_mul = false;
24812 
24813  if (is_generally_string_node(branch))
24814  return true;
24815 
24816  const lexer::parser_helper::token_advance_mode hold = prsrhlpr_t::e_hold;
24817 
24818  switch (token)
24819  {
24820  case token_t::e_lcrlbracket : implied_mul = token_is(token_t::e_lbracket ,hold) ||
24821  token_is(token_t::e_lcrlbracket,hold) ||
24822  token_is(token_t::e_lsqrbracket,hold) ;
24823  break;
24824 
24825  case token_t::e_lbracket : implied_mul = token_is(token_t::e_lbracket ,hold) ||
24826  token_is(token_t::e_lcrlbracket,hold) ||
24827  token_is(token_t::e_lsqrbracket,hold) ;
24828  break;
24829 
24830  case token_t::e_lsqrbracket : implied_mul = token_is(token_t::e_lbracket ,hold) ||
24831  token_is(token_t::e_lcrlbracket,hold) ||
24832  token_is(token_t::e_lsqrbracket,hold) ;
24833  break;
24834 
24835  default : return true;
24836  }
24837 
24838  if (implied_mul)
24839  {
24840  if (!settings_.commutative_check_enabled())
24841  {
24842  set_error(
24844  current_token(),
24845  "ERR181 - Invalid sequence of brackets",
24847 
24848  return false;
24849  }
24850  else if (token_t::e_eof != current_token().type)
24851  {
24852  lexer().insert_front(current_token().type);
24853  lexer().insert_front(token_t::e_mul);
24854  next_token();
24855  }
24856  }
24857 
24858  return true;
24859  }
24860 
24862  {
24863  const std::string symbol = current_token().value;
24864 
24865  // Are we dealing with a variable or a special constant?
24866  expression_node_ptr variable = symtab_store_.get_variable(symbol);
24867 
24868  if (variable)
24869  {
24870  if (symtab_store_.is_constant_node(symbol))
24871  {
24872  variable = expression_generator_(variable->value());
24873  }
24874 
24875  if (!post_variable_process(symbol))
24876  return error_node();
24877 
24878  lodge_symbol(symbol,e_st_variable);
24879  next_token();
24880 
24881  return variable;
24882  }
24883 
24884  // Are we dealing with a locally defined variable, vector or string?
24885  if (!sem_.empty())
24886  {
24887  scope_element& se = sem_.get_active_element(symbol);
24888 
24889  if (se.active && details::imatch(se.name, symbol))
24890  {
24891  if (scope_element::e_variable == se.type)
24892  {
24893  se.active = true;
24894  lodge_symbol(symbol,e_st_local_variable);
24895 
24896  if (!post_variable_process(symbol))
24897  return error_node();
24898 
24899  next_token();
24900 
24901  return se.var_node;
24902  }
24903  else if (scope_element::e_vector == se.type)
24904  {
24905  return parse_vector();
24906  }
24907  #ifndef exprtk_disable_string_capabilities
24908  else if (scope_element::e_string == se.type)
24909  {
24910  return parse_string();
24911  }
24912  #endif
24913  }
24914  }
24915 
24916  #ifndef exprtk_disable_string_capabilities
24917  // Are we dealing with a string variable?
24918  if (symtab_store_.is_stringvar(symbol))
24919  {
24920  return parse_string();
24921  }
24922  #endif
24923 
24924  {
24925  // Are we dealing with a function?
24926  ifunction<T>* function = symtab_store_.get_function(symbol);
24927 
24928  if (function)
24929  {
24930  lodge_symbol(symbol,e_st_function);
24931 
24932  expression_node_ptr func_node =
24933  parse_function_invocation(function,symbol);
24934 
24935  if (func_node)
24936  return func_node;
24937  else
24938  {
24939  set_error(
24941  current_token(),
24942  "ERR182 - Failed to generate node for function: '" + symbol + "'",
24944 
24945  return error_node();
24946  }
24947  }
24948  }
24949 
24950  {
24951  // Are we dealing with a vararg function?
24952  ivararg_function<T>* vararg_function = symtab_store_.get_vararg_function(symbol);
24953 
24954  if (vararg_function)
24955  {
24956  lodge_symbol(symbol,e_st_function);
24957 
24958  expression_node_ptr vararg_func_node =
24959  parse_vararg_function_call(vararg_function, symbol);
24960 
24961  if (vararg_func_node)
24962  return vararg_func_node;
24963  else
24964  {
24965  set_error(
24967  current_token(),
24968  "ERR183 - Failed to generate node for vararg function: '" + symbol + "'",
24970 
24971  return error_node();
24972  }
24973  }
24974  }
24975 
24976  {
24977  // Are we dealing with a vararg generic function?
24978  igeneric_function<T>* generic_function = symtab_store_.get_generic_function(symbol);
24979 
24980  if (generic_function)
24981  {
24982  lodge_symbol(symbol,e_st_function);
24983 
24984  expression_node_ptr genericfunc_node =
24985  parse_generic_function_call(generic_function, symbol);
24986 
24987  if (genericfunc_node)
24988  return genericfunc_node;
24989  else
24990  {
24991  set_error(
24993  current_token(),
24994  "ERR184 - Failed to generate node for generic function: '" + symbol + "'",
24996 
24997  return error_node();
24998  }
24999  }
25000  }
25001 
25002  #ifndef exprtk_disable_string_capabilities
25003  {
25004  // Are we dealing with a vararg string returning function?
25005  igeneric_function<T>* string_function = symtab_store_.get_string_function(symbol);
25006 
25007  if (string_function)
25008  {
25009  lodge_symbol(symbol,e_st_function);
25010 
25011  expression_node_ptr stringfunc_node =
25012  parse_string_function_call(string_function, symbol);
25013 
25014  if (stringfunc_node)
25015  return stringfunc_node;
25016  else
25017  {
25018  set_error(
25020  current_token(),
25021  "ERR185 - Failed to generate node for string function: '" + symbol + "'",
25023 
25024  return error_node();
25025  }
25026  }
25027  }
25028  #endif
25029 
25030  // Are we dealing with a vector?
25031  if (symtab_store_.is_vector(symbol))
25032  {
25033  lodge_symbol(symbol,e_st_vector);
25034  return parse_vector();
25035  }
25036 
25037  if (details::is_reserved_symbol(symbol))
25038  {
25039  if (
25040  settings_.function_enabled(symbol) ||
25041  !details::is_base_function(symbol)
25042  )
25043  {
25044  set_error(
25046  current_token(),
25047  "ERR186 - Invalid use of reserved symbol '" + symbol + "'",
25049 
25050  return error_node();
25051  }
25052  }
25053 
25054  // Should we handle unknown symbols?
25055  if (resolve_unknown_symbol_ && unknown_symbol_resolver_)
25056  {
25057  if (!(settings_.rsrvd_sym_usr_disabled() && details::is_reserved_symbol(symbol)))
25058  {
25059  symbol_table_t& symtab = symtab_store_.get_symbol_table();
25060 
25061  std::string error_message;
25062 
25063  if (unknown_symbol_resolver::e_usrmode_default == unknown_symbol_resolver_->mode)
25064  {
25065  T default_value = T(0);
25066 
25067  typename unknown_symbol_resolver::usr_symbol_type usr_symbol_type;
25068 
25069  if (unknown_symbol_resolver_->process(symbol, usr_symbol_type, default_value, error_message))
25070  {
25071  bool create_result = false;
25072 
25073  switch (usr_symbol_type)
25074  {
25075  case unknown_symbol_resolver::e_usr_variable_type : create_result = symtab.create_variable(symbol, default_value);
25076  break;
25077 
25078  case unknown_symbol_resolver::e_usr_constant_type : create_result = symtab.add_constant(symbol, default_value);
25079  break;
25080 
25081  default : create_result = false;
25082  }
25083 
25084  if (create_result)
25085  {
25086  expression_node_ptr var = symtab_store_.get_variable(symbol);
25087 
25088  if (var)
25089  {
25090  if (symtab_store_.is_constant_node(symbol))
25091  {
25092  var = expression_generator_(var->value());
25093  }
25094 
25095  lodge_symbol(symbol,e_st_variable);
25096 
25097  if (!post_variable_process(symbol))
25098  return error_node();
25099 
25100  next_token();
25101 
25102  return var;
25103  }
25104  }
25105  }
25106 
25107  set_error(
25109  current_token(),
25110  "ERR187 - Failed to create variable: '" + symbol + "'" +
25111  (error_message.empty() ? "" : " - " + error_message),
25113 
25114  }
25115  else if (unknown_symbol_resolver::e_usrmode_extended == unknown_symbol_resolver_->mode)
25116  {
25117  if (unknown_symbol_resolver_->process(symbol, symtab, error_message))
25118  {
25119  expression_node_ptr result = parse_symtab_symbol();
25120 
25121  if (result)
25122  {
25123  return result;
25124  }
25125  }
25126 
25127  set_error(
25129  current_token(),
25130  "ERR188 - Failed to resolve symbol: '" + symbol + "'" +
25131  (error_message.empty() ? "" : " - " + error_message),
25133  }
25134 
25135  return error_node();
25136  }
25137  }
25138 
25139  set_error(
25141  current_token(),
25142  "ERR189 - Undefined symbol: '" + symbol + "'",
25144 
25145  return error_node();
25146  }
25147 
25149  {
25150  static const std::string symbol_if = "if" ;
25151  static const std::string symbol_while = "while" ;
25152  static const std::string symbol_repeat = "repeat" ;
25153  static const std::string symbol_for = "for" ;
25154  static const std::string symbol_switch = "switch" ;
25155  static const std::string symbol_null = "null" ;
25156  static const std::string symbol_break = "break" ;
25157  static const std::string symbol_continue = "continue";
25158  static const std::string symbol_var = "var" ;
25159  static const std::string symbol_swap = "swap" ;
25160  static const std::string symbol_return = "return" ;
25161 
25162  if (valid_vararg_operation(current_token().value))
25163  {
25164  return parse_vararg_function();
25165  }
25166  else if (valid_base_operation(current_token().value))
25167  {
25168  return parse_base_operation();
25169  }
25170  else if (
25171  details::imatch(current_token().value, symbol_if) &&
25172  settings_.control_struct_enabled(current_token().value)
25173  )
25174  {
25175  return parse_conditional_statement();
25176  }
25177  else if (
25178  details::imatch(current_token().value, symbol_while) &&
25179  settings_.control_struct_enabled(current_token().value)
25180  )
25181  {
25182  return parse_while_loop();
25183  }
25184  else if (
25185  details::imatch(current_token().value, symbol_repeat) &&
25186  settings_.control_struct_enabled(current_token().value)
25187  )
25188  {
25189  return parse_repeat_until_loop();
25190  }
25191  else if (
25192  details::imatch(current_token().value, symbol_for) &&
25193  settings_.control_struct_enabled(current_token().value)
25194  )
25195  {
25196  return parse_for_loop();
25197  }
25198  else if (
25199  details::imatch(current_token().value, symbol_switch) &&
25200  settings_.control_struct_enabled(current_token().value)
25201  )
25202  {
25203  return parse_switch_statement();
25204  }
25205  else if (details::is_valid_sf_symbol(current_token().value))
25206  {
25207  return parse_special_function();
25208  }
25209  else if (details::imatch(current_token().value, symbol_null))
25210  {
25211  return parse_null_statement();
25212  }
25213  #ifndef exprtk_disable_break_continue
25214  else if (details::imatch(current_token().value, symbol_break))
25215  {
25216  return parse_break_statement();
25217  }
25218  else if (details::imatch(current_token().value, symbol_continue))
25219  {
25220  return parse_continue_statement();
25221  }
25222  #endif
25223  else if (details::imatch(current_token().value, symbol_var))
25224  {
25225  return parse_define_var_statement();
25226  }
25227  else if (details::imatch(current_token().value, symbol_swap))
25228  {
25229  return parse_swap_statement();
25230  }
25231  #ifndef exprtk_disable_return_statement
25232  else if (
25233  details::imatch(current_token().value, symbol_return) &&
25234  settings_.control_struct_enabled(current_token().value)
25235  )
25236  {
25237  return parse_return_statement();
25238  }
25239  #endif
25240  else if (symtab_store_.valid() || !sem_.empty())
25241  {
25242  return parse_symtab_symbol();
25243  }
25244  else
25245  {
25246  set_error(
25248  current_token(),
25249  "ERR190 - Variable or function detected, yet symbol-table is invalid, Symbol: " + current_token().value,
25251 
25252  return error_node();
25253  }
25254  }
25255 
25256  inline expression_node_ptr parse_branch(precedence_level precedence = e_level00)
25257  {
25258  expression_node_ptr branch = error_node();
25259 
25260  if (token_t::e_number == current_token().type)
25261  {
25262  T numeric_value = T(0);
25263 
25264  if (details::string_to_real(current_token().value, numeric_value))
25265  {
25266  expression_node_ptr literal_exp = expression_generator_(numeric_value);
25267 
25268  if (0 == literal_exp)
25269  {
25270  set_error(
25272  current_token(),
25273  "ERR191 - Failed generate node for scalar: '" + current_token().value + "'",
25275 
25276  return error_node();
25277  }
25278 
25279  next_token();
25280  branch = literal_exp;
25281  }
25282  else
25283  {
25284  set_error(
25286  current_token(),
25287  "ERR192 - Failed to convert '" + current_token().value + "' to a number",
25289 
25290  return error_node();
25291  }
25292  }
25293  else if (token_t::e_symbol == current_token().type)
25294  {
25295  branch = parse_symbol();
25296  }
25297  #ifndef exprtk_disable_string_capabilities
25298  else if (token_t::e_string == current_token().type)
25299  {
25300  branch = parse_const_string();
25301  }
25302  #endif
25303  else if (token_t::e_lbracket == current_token().type)
25304  {
25305  next_token();
25306 
25307  if (0 == (branch = parse_expression()))
25308  return error_node();
25309  else if (!token_is(token_t::e_rbracket))
25310  {
25311  set_error(
25313  current_token(),
25314  "ERR193 - Expected ')' instead of: '" + current_token().value + "'",
25316 
25317  free_node(node_allocator_,branch);
25318 
25319  return error_node();
25320  }
25321  else if (!post_bracket_process(token_t::e_lbracket,branch))
25322  {
25323  free_node(node_allocator_,branch);
25324 
25325  return error_node();
25326  }
25327  }
25328  else if (token_t::e_lsqrbracket == current_token().type)
25329  {
25330  next_token();
25331 
25332  if (0 == (branch = parse_expression()))
25333  return error_node();
25334  else if (!token_is(token_t::e_rsqrbracket))
25335  {
25336  set_error(
25338  current_token(),
25339  "ERR194 - Expected ']' instead of: '" + current_token().value + "'",
25341 
25342  free_node(node_allocator_,branch);
25343 
25344  return error_node();
25345  }
25346  else if (!post_bracket_process(token_t::e_lsqrbracket,branch))
25347  {
25348  free_node(node_allocator_,branch);
25349 
25350  return error_node();
25351  }
25352  }
25353  else if (token_t::e_lcrlbracket == current_token().type)
25354  {
25355  next_token();
25356 
25357  if (0 == (branch = parse_expression()))
25358  return error_node();
25359  else if (!token_is(token_t::e_rcrlbracket))
25360  {
25361  set_error(
25363  current_token(),
25364  "ERR195 - Expected '}' instead of: '" + current_token().value + "'",
25366 
25367  free_node(node_allocator_,branch);
25368 
25369  return error_node();
25370  }
25371  else if (!post_bracket_process(token_t::e_lcrlbracket,branch))
25372  {
25373  free_node(node_allocator_,branch);
25374 
25375  return error_node();
25376  }
25377  }
25378  else if (token_t::e_sub == current_token().type)
25379  {
25380  next_token();
25381  branch = parse_expression(e_level11);
25382 
25383  if (
25384  branch &&
25385  !(
25386  details::is_neg_unary_node (branch) &&
25387  simplify_unary_negation_branch(branch)
25388  )
25389  )
25390  {
25391  branch = expression_generator_(details::e_neg,branch);
25392  }
25393  }
25394  else if (token_t::e_add == current_token().type)
25395  {
25396  next_token();
25397  branch = parse_expression(e_level13);
25398  }
25399  else if (token_t::e_eof == current_token().type)
25400  {
25401  set_error(
25403  current_token(),
25404  "ERR196 - Premature end of expression[1]",
25406 
25407  return error_node();
25408  }
25409  else
25410  {
25411  set_error(
25413  current_token(),
25414  "ERR197 - Premature end of expression[2]",
25416 
25417  return error_node();
25418  }
25419 
25420  if (
25421  branch &&
25422  (e_level00 == precedence) &&
25423  token_is(token_t::e_ternary,prsrhlpr_t::e_hold)
25424  )
25425  {
25426  branch = parse_ternary_conditional_statement(branch);
25427  }
25428 
25429  parse_pending_string_rangesize(branch);
25430 
25431  return branch;
25432  }
25433 
25434  template <typename Type>
25436  {
25437  public:
25438 
25440  typedef expression_node_ptr (*synthesize_functor_t)(expression_generator<T>&, const details::operator_type& operation, expression_node_ptr (&branch)[2]);
25441  typedef std::map<std::string,synthesize_functor_t> synthesize_map_t;
25442  typedef typename exprtk::parser<Type> parser_t;
25443  typedef const Type& vtype;
25444  typedef const Type ctype;
25445 
25446  inline void init_synthesize_map()
25447  {
25448  #ifndef exprtk_disable_enhanced_features
25449  synthesize_map_["(v)o(v)"] = synthesize_vov_expression::process;
25450  synthesize_map_["(c)o(v)"] = synthesize_cov_expression::process;
25451  synthesize_map_["(v)o(c)"] = synthesize_voc_expression::process;
25452 
25453  #define register_synthezier(S) \
25454  synthesize_map_[S ::node_type::id()] = S ::process; \
25455 
25456  register_synthezier(synthesize_vovov_expression0)
25457  register_synthezier(synthesize_vovov_expression1)
25458  register_synthezier(synthesize_vovoc_expression0)
25459  register_synthezier(synthesize_vovoc_expression1)
25460  register_synthezier(synthesize_vocov_expression0)
25461  register_synthezier(synthesize_vocov_expression1)
25462  register_synthezier(synthesize_covov_expression0)
25463  register_synthezier(synthesize_covov_expression1)
25464  register_synthezier(synthesize_covoc_expression0)
25465  register_synthezier(synthesize_covoc_expression1)
25466  register_synthezier(synthesize_cocov_expression1)
25467  register_synthezier(synthesize_vococ_expression0)
25468 
25469  register_synthezier(synthesize_vovovov_expression0)
25470  register_synthezier(synthesize_vovovoc_expression0)
25471  register_synthezier(synthesize_vovocov_expression0)
25472  register_synthezier(synthesize_vocovov_expression0)
25473  register_synthezier(synthesize_covovov_expression0)
25474  register_synthezier(synthesize_covocov_expression0)
25475  register_synthezier(synthesize_vocovoc_expression0)
25476  register_synthezier(synthesize_covovoc_expression0)
25477  register_synthezier(synthesize_vococov_expression0)
25478 
25479  register_synthezier(synthesize_vovovov_expression1)
25480  register_synthezier(synthesize_vovovoc_expression1)
25481  register_synthezier(synthesize_vovocov_expression1)
25482  register_synthezier(synthesize_vocovov_expression1)
25483  register_synthezier(synthesize_covovov_expression1)
25484  register_synthezier(synthesize_covocov_expression1)
25485  register_synthezier(synthesize_vocovoc_expression1)
25486  register_synthezier(synthesize_covovoc_expression1)
25487  register_synthezier(synthesize_vococov_expression1)
25488 
25489  register_synthezier(synthesize_vovovov_expression2)
25490  register_synthezier(synthesize_vovovoc_expression2)
25491  register_synthezier(synthesize_vovocov_expression2)
25492  register_synthezier(synthesize_vocovov_expression2)
25493  register_synthezier(synthesize_covovov_expression2)
25494  register_synthezier(synthesize_covocov_expression2)
25495  register_synthezier(synthesize_vocovoc_expression2)
25496  register_synthezier(synthesize_covovoc_expression2)
25497 
25498  register_synthezier(synthesize_vovovov_expression3)
25499  register_synthezier(synthesize_vovovoc_expression3)
25500  register_synthezier(synthesize_vovocov_expression3)
25501  register_synthezier(synthesize_vocovov_expression3)
25502  register_synthezier(synthesize_covovov_expression3)
25503  register_synthezier(synthesize_covocov_expression3)
25504  register_synthezier(synthesize_vocovoc_expression3)
25505  register_synthezier(synthesize_covovoc_expression3)
25506  register_synthezier(synthesize_vococov_expression3)
25507 
25508  register_synthezier(synthesize_vovovov_expression4)
25509  register_synthezier(synthesize_vovovoc_expression4)
25510  register_synthezier(synthesize_vovocov_expression4)
25511  register_synthezier(synthesize_vocovov_expression4)
25512  register_synthezier(synthesize_covovov_expression4)
25513  register_synthezier(synthesize_covocov_expression4)
25514  register_synthezier(synthesize_vocovoc_expression4)
25515  register_synthezier(synthesize_covovoc_expression4)
25516  #endif
25517  }
25518 
25519  inline void set_parser(parser_t& p)
25520  {
25521  parser_ = &p;
25522  }
25523 
25524  inline void set_uom(unary_op_map_t& unary_op_map)
25525  {
25526  unary_op_map_ = &unary_op_map;
25527  }
25528 
25529  inline void set_bom(binary_op_map_t& binary_op_map)
25530  {
25531  binary_op_map_ = &binary_op_map;
25532  }
25533 
25534  inline void set_ibom(inv_binary_op_map_t& inv_binary_op_map)
25535  {
25536  inv_binary_op_map_ = &inv_binary_op_map;
25537  }
25538 
25539  inline void set_sf3m(sf3_map_t& sf3_map)
25540  {
25541  sf3_map_ = &sf3_map;
25542  }
25543 
25544  inline void set_sf4m(sf4_map_t& sf4_map)
25545  {
25546  sf4_map_ = &sf4_map;
25547  }
25548 
25550  {
25551  node_allocator_ = &na;
25552  }
25553 
25554  inline void set_strength_reduction_state(const bool enabled)
25555  {
25556  strength_reduction_enabled_ = enabled;
25557  }
25558 
25559  inline bool strength_reduction_enabled() const
25560  {
25561  return strength_reduction_enabled_;
25562  }
25563 
25564  inline bool valid_operator(const details::operator_type& operation, binary_functor_t& bop)
25565  {
25566  typename binary_op_map_t::iterator bop_itr = binary_op_map_->find(operation);
25567 
25568  if ((*binary_op_map_).end() == bop_itr)
25569  return false;
25570 
25571  bop = bop_itr->second;
25572 
25573  return true;
25574  }
25575 
25576  inline bool valid_operator(const details::operator_type& operation, unary_functor_t& uop)
25577  {
25578  typename unary_op_map_t::iterator uop_itr = unary_op_map_->find(operation);
25579 
25580  if ((*unary_op_map_).end() == uop_itr)
25581  return false;
25582 
25583  uop = uop_itr->second;
25584 
25585  return true;
25586  }
25587 
25589  {
25590  return (*inv_binary_op_map_).find(bop)->second;
25591  }
25592 
25593  inline expression_node_ptr operator() (const Type& v) const
25594  {
25595  return node_allocator_->allocate<literal_node_t>(v);
25596  }
25597 
25598  #ifndef exprtk_disable_string_capabilities
25599  inline expression_node_ptr operator() (const std::string& s) const
25600  {
25601  return node_allocator_->allocate<string_literal_node_t>(s);
25602  }
25603 
25604  inline expression_node_ptr operator() (std::string& s, range_t& rp) const
25605  {
25606  return node_allocator_->allocate_rr<string_range_node_t>(s,rp);
25607  }
25608 
25609  inline expression_node_ptr operator() (const std::string& s, range_t& rp) const
25610  {
25611  return node_allocator_->allocate_tt<const_string_range_node_t>(s,rp);
25612  }
25613 
25614  inline expression_node_ptr operator() (expression_node_ptr branch, range_t& rp) const
25615  {
25616  if (is_generally_string_node(branch))
25617  return node_allocator_->allocate_tt<generic_string_range_node_t>(branch,rp);
25618  else
25619  return error_node();
25620  }
25621  #endif
25622 
25623  inline bool unary_optimisable(const details::operator_type& operation) const
25624  {
25625  return (details::e_abs == operation) || (details::e_acos == operation) ||
25626  (details::e_acosh == operation) || (details::e_asin == operation) ||
25627  (details::e_asinh == operation) || (details::e_atan == operation) ||
25628  (details::e_atanh == operation) || (details::e_ceil == operation) ||
25629  (details::e_cos == operation) || (details::e_cosh == operation) ||
25630  (details::e_exp == operation) || (details::e_expm1 == operation) ||
25631  (details::e_floor == operation) || (details::e_log == operation) ||
25632  (details::e_log10 == operation) || (details::e_log2 == operation) ||
25633  (details::e_log1p == operation) || (details::e_neg == operation) ||
25634  (details::e_pos == operation) || (details::e_round == operation) ||
25635  (details::e_sin == operation) || (details::e_sinc == operation) ||
25636  (details::e_sinh == operation) || (details::e_sqrt == operation) ||
25637  (details::e_tan == operation) || (details::e_tanh == operation) ||
25638  (details::e_cot == operation) || (details::e_sec == operation) ||
25639  (details::e_csc == operation) || (details::e_r2d == operation) ||
25640  (details::e_d2r == operation) || (details::e_d2g == operation) ||
25641  (details::e_g2d == operation) || (details::e_notl == operation) ||
25642  (details::e_sgn == operation) || (details::e_erf == operation) ||
25643  (details::e_erfc == operation) || (details::e_ncdf == operation) ||
25644  (details::e_frac == operation) || (details::e_trunc == operation) ;
25645  }
25646 
25647  inline bool sf3_optimisable(const std::string& sf3id, trinary_functor_t& tfunc)
25648  {
25649  typename sf3_map_t::iterator itr = sf3_map_->find(sf3id);
25650 
25651  if (sf3_map_->end() == itr)
25652  return false;
25653  else
25654  tfunc = itr->second.first;
25655 
25656  return true;
25657  }
25658 
25659  inline bool sf4_optimisable(const std::string& sf4id, quaternary_functor_t& qfunc)
25660  {
25661  typename sf4_map_t::iterator itr = sf4_map_->find(sf4id);
25662 
25663  if (sf4_map_->end() == itr)
25664  return false;
25665  else
25666  qfunc = itr->second.first;
25667 
25668  return true;
25669  }
25670 
25671  inline bool sf3_optimisable(const std::string& sf3id, details::operator_type& operation)
25672  {
25673  typename sf3_map_t::iterator itr = sf3_map_->find(sf3id);
25674 
25675  if (sf3_map_->end() == itr)
25676  return false;
25677  else
25678  operation = itr->second.second;
25679 
25680  return true;
25681  }
25682 
25683  inline bool sf4_optimisable(const std::string& sf4id, details::operator_type& operation)
25684  {
25685  typename sf4_map_t::iterator itr = sf4_map_->find(sf4id);
25686 
25687  if (sf4_map_->end() == itr)
25688  return false;
25689  else
25690  operation = itr->second.second;
25691 
25692  return true;
25693  }
25694 
25695  inline expression_node_ptr operator() (const details::operator_type& operation, expression_node_ptr (&branch)[1])
25696  {
25697  if (0 == branch[0])
25698  {
25699  return error_node();
25700  }
25701  else if (details::is_null_node(branch[0]))
25702  {
25703  return branch[0];
25704  }
25705  else if (details::is_break_node(branch[0]))
25706  {
25707  return error_node();
25708  }
25709  else if (details::is_continue_node(branch[0]))
25710  {
25711  return error_node();
25712  }
25713  else if (details::is_constant_node(branch[0]))
25714  {
25715  return synthesize_expression<unary_node_t,1>(operation,branch);
25716  }
25717  else if (unary_optimisable(operation) && details::is_variable_node(branch[0]))
25718  {
25719  return synthesize_uv_expression(operation,branch);
25720  }
25721  else if (unary_optimisable(operation) && details::is_ivector_node(branch[0]))
25722  {
25723  return synthesize_uvec_expression(operation,branch);
25724  }
25725  else
25726  return synthesize_unary_expression(operation,branch);
25727  }
25728 
25729  inline bool is_assignment_operation(const details::operator_type& operation) const
25730  {
25731  return (
25732  (details::e_addass == operation) ||
25733  (details::e_subass == operation) ||
25734  (details::e_mulass == operation) ||
25735  (details::e_divass == operation) ||
25736  (details::e_modass == operation)
25737  ) &&
25738  parser_->settings_.assignment_enabled(operation);
25739  }
25740 
25741  #ifndef exprtk_disable_string_capabilities
25742  inline bool valid_string_operation(const details::operator_type& operation) const
25743  {
25744  return (details::e_add == operation) ||
25745  (details::e_lt == operation) ||
25746  (details::e_lte == operation) ||
25747  (details::e_gt == operation) ||
25748  (details::e_gte == operation) ||
25749  (details::e_eq == operation) ||
25750  (details::e_ne == operation) ||
25751  (details::e_in == operation) ||
25752  (details::e_like == operation) ||
25753  (details::e_ilike == operation) ||
25754  (details::e_assign == operation) ||
25755  (details::e_addass == operation) ||
25756  (details::e_swap == operation) ;
25757  }
25758  #else
25759  inline bool valid_string_operation(const details::operator_type&) const
25760  {
25761  return false;
25762  }
25763  #endif
25764 
25765  inline std::string to_str(const details::operator_type& operation) const
25766  {
25767  switch (operation)
25768  {
25769  case details::e_add : return "+" ;
25770  case details::e_sub : return "-" ;
25771  case details::e_mul : return "*" ;
25772  case details::e_div : return "/" ;
25773  case details::e_mod : return "%" ;
25774  case details::e_pow : return "^" ;
25775  case details::e_lt : return "<" ;
25776  case details::e_lte : return "<=" ;
25777  case details::e_gt : return ">" ;
25778  case details::e_gte : return ">=" ;
25779  case details::e_eq : return "==" ;
25780  case details::e_ne : return "!=" ;
25781  case details::e_and : return "and" ;
25782  case details::e_nand : return "nand" ;
25783  case details::e_or : return "or" ;
25784  case details::e_nor : return "nor" ;
25785  case details::e_xor : return "xor" ;
25786  case details::e_xnor : return "xnor" ;
25787  default : return "UNKNOWN";
25788  }
25789  }
25790 
25791  inline bool operation_optimisable(const details::operator_type& operation) const
25792  {
25793  return (details::e_add == operation) ||
25794  (details::e_sub == operation) ||
25795  (details::e_mul == operation) ||
25796  (details::e_div == operation) ||
25797  (details::e_mod == operation) ||
25798  (details::e_pow == operation) ||
25799  (details::e_lt == operation) ||
25800  (details::e_lte == operation) ||
25801  (details::e_gt == operation) ||
25802  (details::e_gte == operation) ||
25803  (details::e_eq == operation) ||
25804  (details::e_ne == operation) ||
25805  (details::e_and == operation) ||
25806  (details::e_nand == operation) ||
25807  (details::e_or == operation) ||
25808  (details::e_nor == operation) ||
25809  (details::e_xor == operation) ||
25810  (details::e_xnor == operation) ;
25811  }
25812 
25813  inline std::string branch_to_id(expression_node_ptr branch)
25814  {
25815  static const std::string null_str ("(null)" );
25816  static const std::string const_str ("(c)" );
25817  static const std::string var_str ("(v)" );
25818  static const std::string vov_str ("(vov)" );
25819  static const std::string cov_str ("(cov)" );
25820  static const std::string voc_str ("(voc)" );
25821  static const std::string str_str ("(s)" );
25822  static const std::string strrng_str ("(rngs)" );
25823  static const std::string cs_str ("(cs)" );
25824  static const std::string cstrrng_str("(crngs)");
25825 
25826  if (details::is_null_node(branch))
25827  return null_str;
25828  else if (details::is_constant_node(branch))
25829  return const_str;
25830  else if (details::is_variable_node(branch))
25831  return var_str;
25832  else if (details::is_vov_node(branch))
25833  return vov_str;
25834  else if (details::is_cov_node(branch))
25835  return cov_str;
25836  else if (details::is_voc_node(branch))
25837  return voc_str;
25838  else if (details::is_string_node(branch))
25839  return str_str;
25840  else if (details::is_const_string_node(branch))
25841  return cs_str;
25842  else if (details::is_string_range_node(branch))
25843  return strrng_str;
25844  else if (details::is_const_string_range_node(branch))
25845  return cstrrng_str;
25846  else if (details::is_t0ot1ot2_node(branch))
25847  return "(" + dynamic_cast<details::T0oT1oT2_base_node<T>*>(branch)->type_id() + ")";
25848  else if (details::is_t0ot1ot2ot3_node(branch))
25849  return "(" + dynamic_cast<details::T0oT1oT2oT3_base_node<T>*>(branch)->type_id() + ")";
25850  else
25851  return "ERROR";
25852  }
25853 
25854  inline std::string branch_to_id(expression_node_ptr (&branch)[2])
25855  {
25856  return branch_to_id(branch[0]) + std::string("o") + branch_to_id(branch[1]);
25857  }
25858 
25859  inline bool cov_optimisable(const details::operator_type& operation, expression_node_ptr (&branch)[2]) const
25860  {
25861  if (!operation_optimisable(operation))
25862  return false;
25863  else
25864  return details::is_constant_node(branch[0]) &&
25865  details::is_variable_node(branch[1]) ;
25866  }
25867 
25868  inline bool voc_optimisable(const details::operator_type& operation, expression_node_ptr (&branch)[2]) const
25869  {
25870  if (!operation_optimisable(operation))
25871  return false;
25872  else
25873  return details::is_variable_node(branch[0]) &&
25874  details::is_constant_node(branch[1]) ;
25875  }
25876 
25877  inline bool vov_optimisable(const details::operator_type& operation, expression_node_ptr (&branch)[2]) const
25878  {
25879  if (!operation_optimisable(operation))
25880  return false;
25881  else
25882  return details::is_variable_node(branch[0]) &&
25883  details::is_variable_node(branch[1]) ;
25884  }
25885 
25886  inline bool cob_optimisable(const details::operator_type& operation, expression_node_ptr (&branch)[2]) const
25887  {
25888  if (!operation_optimisable(operation))
25889  return false;
25890  else
25891  return details::is_constant_node(branch[0]) &&
25892  !details::is_constant_node(branch[1]) ;
25893  }
25894 
25895  inline bool boc_optimisable(const details::operator_type& operation, expression_node_ptr (&branch)[2]) const
25896  {
25897  if (!operation_optimisable(operation))
25898  return false;
25899  else
25900  return !details::is_constant_node(branch[0]) &&
25901  details::is_constant_node(branch[1]) ;
25902  }
25903 
25904  inline bool cocob_optimisable(const details::operator_type& operation, expression_node_ptr (&branch)[2]) const
25905  {
25906  if (
25907  (details::e_add == operation) ||
25908  (details::e_sub == operation) ||
25909  (details::e_mul == operation) ||
25910  (details::e_div == operation)
25911  )
25912  {
25913  return (details::is_constant_node(branch[0]) && details::is_cob_node(branch[1])) ||
25914  (details::is_constant_node(branch[1]) && details::is_cob_node(branch[0])) ;
25915  }
25916  else
25917  return false;
25918  }
25919 
25920  inline bool coboc_optimisable(const details::operator_type& operation, expression_node_ptr (&branch)[2]) const
25921  {
25922  if (
25923  (details::e_add == operation) ||
25924  (details::e_sub == operation) ||
25925  (details::e_mul == operation) ||
25926  (details::e_div == operation)
25927  )
25928  {
25929  return (details::is_constant_node(branch[0]) && details::is_boc_node(branch[1])) ||
25930  (details::is_constant_node(branch[1]) && details::is_boc_node(branch[0])) ;
25931  }
25932  else
25933  return false;
25934  }
25935 
25936  inline bool uvouv_optimisable(const details::operator_type& operation, expression_node_ptr (&branch)[2]) const
25937  {
25938  if (!operation_optimisable(operation))
25939  return false;
25940  else
25941  return details::is_uv_node(branch[0]) &&
25942  details::is_uv_node(branch[1]) ;
25943  }
25944 
25945  inline bool vob_optimisable(const details::operator_type& operation, expression_node_ptr (&branch)[2]) const
25946  {
25947  if (!operation_optimisable(operation))
25948  return false;
25949  else
25950  return details::is_variable_node(branch[0]) &&
25951  !details::is_variable_node(branch[1]) ;
25952  }
25953 
25954  inline bool bov_optimisable(const details::operator_type& operation, expression_node_ptr (&branch)[2]) const
25955  {
25956  if (!operation_optimisable(operation))
25957  return false;
25958  else
25959  return !details::is_variable_node(branch[0]) &&
25960  details::is_variable_node(branch[1]) ;
25961  }
25962 
25963  inline bool binext_optimisable(const details::operator_type& operation, expression_node_ptr (&branch)[2]) const
25964  {
25965  if (!operation_optimisable(operation))
25966  return false;
25967  else
25968  return !details::is_constant_node(branch[0]) ||
25969  !details::is_constant_node(branch[1]) ;
25970  }
25971 
25972  inline bool is_invalid_assignment_op(const details::operator_type& operation, expression_node_ptr (&branch)[2])
25973  {
25974  if (is_assignment_operation(operation))
25975  {
25976  const bool b1_is_genstring = details::is_generally_string_node(branch[1]);
25977 
25978  if (details::is_string_node(branch[0]))
25979  return !b1_is_genstring;
25980  else
25981  return (
25982  !details::is_variable_node (branch[0]) &&
25983  !details::is_vector_elem_node (branch[0]) &&
25984  !details::is_rebasevector_elem_node (branch[0]) &&
25986  !details::is_vector_node (branch[0])
25987  )
25988  || b1_is_genstring;
25989  }
25990  else
25991  return false;
25992  }
25993 
25994  inline bool is_constpow_operation(const details::operator_type& operation, expression_node_ptr(&branch)[2])
25995  {
25996  if (
25997  !details::is_constant_node(branch[1]) ||
25998  details::is_constant_node(branch[0]) ||
25999  details::is_variable_node(branch[0]) ||
26000  details::is_vector_node (branch[0]) ||
26002  )
26003  return false;
26004 
26005  const Type c = static_cast<details::literal_node<Type>*>(branch[1])->value();
26006 
26007  return cardinal_pow_optimisable(operation, c);
26008  }
26009 
26011  {
26012  return (
26013  details::is_break_node (branch[0]) ||
26014  details::is_break_node (branch[1]) ||
26015  details::is_continue_node(branch[0]) ||
26016  details::is_continue_node(branch[1])
26017  );
26018  }
26019 
26020  inline bool is_invalid_string_op(const details::operator_type& operation, expression_node_ptr (&branch)[2])
26021  {
26022  const bool b0_string = is_generally_string_node(branch[0]);
26023  const bool b1_string = is_generally_string_node(branch[1]);
26024 
26025  bool result = false;
26026 
26027  if (b0_string != b1_string)
26028  result = true;
26029  else if (!valid_string_operation(operation) && b0_string && b1_string)
26030  result = true;
26031 
26032  if (result)
26033  {
26034  parser_->set_synthesis_error("Invalid string operation");
26035  }
26036 
26037  return result;
26038  }
26039 
26040  inline bool is_invalid_string_op(const details::operator_type& operation, expression_node_ptr (&branch)[3])
26041  {
26042  const bool b0_string = is_generally_string_node(branch[0]);
26043  const bool b1_string = is_generally_string_node(branch[1]);
26044  const bool b2_string = is_generally_string_node(branch[2]);
26045 
26046  bool result = false;
26047 
26048  if ((b0_string != b1_string) || (b1_string != b2_string))
26049  result = true;
26050  else if ((details::e_inrange != operation) && b0_string && b1_string && b2_string)
26051  result = true;
26052 
26053  if (result)
26054  {
26055  parser_->set_synthesis_error("Invalid string operation");
26056  }
26057 
26058  return result;
26059  }
26060 
26061  inline bool is_string_operation(const details::operator_type& operation, expression_node_ptr (&branch)[2])
26062  {
26063  const bool b0_string = is_generally_string_node(branch[0]);
26064  const bool b1_string = is_generally_string_node(branch[1]);
26065 
26066  return (b0_string && b1_string && valid_string_operation(operation));
26067  }
26068 
26069  inline bool is_string_operation(const details::operator_type& operation, expression_node_ptr (&branch)[3])
26070  {
26071  const bool b0_string = is_generally_string_node(branch[0]);
26072  const bool b1_string = is_generally_string_node(branch[1]);
26073  const bool b2_string = is_generally_string_node(branch[2]);
26074 
26075  return (b0_string && b1_string && b2_string && (details::e_inrange == operation));
26076  }
26077 
26078  #ifndef exprtk_disable_sc_andor
26079  inline bool is_shortcircuit_expression(const details::operator_type& operation) const
26080  {
26081  return (
26082  (details::e_scand == operation) ||
26083  (details::e_scor == operation)
26084  );
26085  }
26086  #else
26087  inline bool is_shortcircuit_expression(const details::operator_type&) const
26088  {
26089  return false;
26090  }
26091  #endif
26092 
26093  inline bool is_null_present(expression_node_ptr (&branch)[2]) const
26094  {
26095  return (
26096  details::is_null_node(branch[0]) ||
26097  details::is_null_node(branch[1])
26098  );
26099  }
26100 
26101  inline bool is_vector_eqineq_logic_operation(const details::operator_type& operation, expression_node_ptr (&branch)[2]) const
26102  {
26103  if (!is_ivector_node(branch[0]) && !is_ivector_node(branch[1]))
26104  return false;
26105  else
26106  return (
26107  (details::e_lt == operation) ||
26108  (details::e_lte == operation) ||
26109  (details::e_gt == operation) ||
26110  (details::e_gte == operation) ||
26111  (details::e_eq == operation) ||
26112  (details::e_ne == operation) ||
26113  (details::e_equal == operation) ||
26114  (details::e_and == operation) ||
26115  (details::e_nand == operation) ||
26116  (details:: e_or == operation) ||
26117  (details:: e_nor == operation) ||
26118  (details:: e_xor == operation) ||
26119  (details::e_xnor == operation)
26120  );
26121  }
26122 
26123  inline bool is_vector_arithmetic_operation(const details::operator_type& operation, expression_node_ptr (&branch)[2]) const
26124  {
26125  if (!is_ivector_node(branch[0]) && !is_ivector_node(branch[1]))
26126  return false;
26127  else
26128  return (
26129  (details::e_add == operation) ||
26130  (details::e_sub == operation) ||
26131  (details::e_mul == operation) ||
26132  (details::e_div == operation) ||
26133  (details::e_pow == operation)
26134  );
26135  }
26136 
26137  inline expression_node_ptr operator() (const details::operator_type& operation, expression_node_ptr (&branch)[2])
26138  {
26139  if ((0 == branch[0]) || (0 == branch[1]))
26140  {
26141  return error_node();
26142  }
26143  else if (is_invalid_string_op(operation,branch))
26144  {
26145  return error_node();
26146  }
26147  else if (is_invalid_assignment_op(operation,branch))
26148  {
26149  return error_node();
26150  }
26151  else if (is_invalid_break_continue_op(branch))
26152  {
26153  return error_node();
26154  }
26155  else if (details::e_assign == operation)
26156  {
26157  return synthesize_assignment_expression(operation, branch);
26158  }
26159  else if (details::e_swap == operation)
26160  {
26161  return synthesize_swap_expression(branch);
26162  }
26163  else if (is_assignment_operation(operation))
26164  {
26165  return synthesize_assignment_operation_expression(operation, branch);
26166  }
26167  else if (is_vector_eqineq_logic_operation(operation, branch))
26168  {
26169  return synthesize_veceqineqlogic_operation_expression(operation, branch);
26170  }
26171  else if (is_vector_arithmetic_operation(operation, branch))
26172  {
26173  return synthesize_vecarithmetic_operation_expression(operation, branch);
26174  }
26175  else if (is_shortcircuit_expression(operation))
26176  {
26177  return synthesize_shortcircuit_expression(operation, branch);
26178  }
26179  else if (is_string_operation(operation, branch))
26180  {
26181  return synthesize_string_expression(operation, branch);
26182  }
26183  else if (is_null_present(branch))
26184  {
26185  return synthesize_null_expression(operation, branch);
26186  }
26187  #ifndef exprtk_disable_cardinal_pow_optimisation
26188  else if (is_constpow_operation(operation, branch))
26189  {
26190  return cardinal_pow_optimisation(branch);
26191  }
26192  #endif
26193 
26194  expression_node_ptr result = error_node();
26195 
26196  #ifndef exprtk_disable_enhanced_features
26197  if (synthesize_expression(operation, branch, result))
26198  {
26199  return result;
26200  }
26201  else
26202  #endif
26203 
26204  {
26205  /*
26206  Possible reductions:
26207  1. c o cob -> cob
26208  2. cob o c -> cob
26209  3. c o boc -> boc
26210  4. boc o c -> boc
26211  */
26212  result = error_node();
26213 
26214  if (cocob_optimisable(operation, branch))
26215  {
26216  result = synthesize_cocob_expression::process((*this), operation, branch);
26217  }
26218  else if (coboc_optimisable(operation, branch) && (0 == result))
26219  {
26220  result = synthesize_coboc_expression::process((*this), operation, branch);
26221  }
26222 
26223  if (result)
26224  return result;
26225  }
26226 
26227  if (uvouv_optimisable(operation, branch))
26228  {
26229  return synthesize_uvouv_expression(operation, branch);
26230  }
26231  else if (vob_optimisable(operation, branch))
26232  {
26233  return synthesize_vob_expression::process((*this), operation, branch);
26234  }
26235  else if (bov_optimisable(operation, branch))
26236  {
26237  return synthesize_bov_expression::process((*this), operation, branch);
26238  }
26239  else if (cob_optimisable(operation, branch))
26240  {
26241  return synthesize_cob_expression::process((*this), operation, branch);
26242  }
26243  else if (boc_optimisable(operation, branch))
26244  {
26245  return synthesize_boc_expression::process((*this), operation, branch);
26246  }
26247  #ifndef exprtk_disable_enhanced_features
26248  else if (cov_optimisable(operation, branch))
26249  {
26250  return synthesize_cov_expression::process((*this), operation, branch);
26251  }
26252  #endif
26253  else if (binext_optimisable(operation, branch))
26254  {
26255  return synthesize_binary_ext_expression::process((*this), operation, branch);
26256  }
26257  else
26258  return synthesize_expression<binary_node_t,2>(operation, branch);
26259  }
26260 
26261  inline expression_node_ptr operator() (const details::operator_type& operation, expression_node_ptr (&branch)[3])
26262  {
26263  if (
26264  (0 == branch[0]) ||
26265  (0 == branch[1]) ||
26266  (0 == branch[2])
26267  )
26268  {
26269  details::free_all_nodes(*node_allocator_,branch);
26270 
26271  return error_node();
26272  }
26273  else if (is_invalid_string_op(operation, branch))
26274  {
26275  return error_node();
26276  }
26277  else if (is_string_operation(operation, branch))
26278  {
26279  return synthesize_string_expression(operation, branch);
26280  }
26281  else
26282  return synthesize_expression<trinary_node_t,3>(operation, branch);
26283  }
26284 
26285  inline expression_node_ptr operator() (const details::operator_type& operation, expression_node_ptr (&branch)[4])
26286  {
26287  return synthesize_expression<quaternary_node_t,4>(operation,branch);
26288  }
26289 
26290  inline expression_node_ptr operator() (const details::operator_type& operation, expression_node_ptr b0)
26291  {
26292  expression_node_ptr branch[1] = { b0 };
26293  return (*this)(operation,branch);
26294  }
26295 
26297  {
26298  if ((0 == b0) || (0 == b1))
26299  return error_node();
26300  else
26301  {
26302  expression_node_ptr branch[2] = { b0, b1 };
26303  return expression_generator<Type>::operator()(operation,branch);
26304  }
26305  }
26306 
26308  expression_node_ptr consequent,
26309  expression_node_ptr alternative) const
26310  {
26311  if ((0 == condition) || (0 == consequent))
26312  {
26313  free_node(*node_allocator_, condition);
26314  free_node(*node_allocator_, consequent);
26315  free_node(*node_allocator_, alternative);
26316 
26317  return error_node();
26318  }
26319  // Can the condition be immediately evaluated? if so optimise.
26320  else if (details::is_constant_node(condition))
26321  {
26322  // True branch
26323  if (details::is_true(condition))
26324  {
26325  free_node(*node_allocator_, condition);
26326  free_node(*node_allocator_, alternative);
26327 
26328  return consequent;
26329  }
26330  // False branch
26331  else
26332  {
26333  free_node(*node_allocator_, condition);
26334  free_node(*node_allocator_, consequent);
26335 
26336  if (alternative)
26337  return alternative;
26338  else
26339  return node_allocator_->allocate<details::null_node<T> >();
26340  }
26341  }
26342  else if ((0 != consequent) && (0 != alternative))
26343  {
26344  return node_allocator_->
26345  allocate<conditional_node_t>(condition, consequent, alternative);
26346  }
26347  else
26348  return node_allocator_->
26349  allocate<cons_conditional_node_t>(condition, consequent);
26350  }
26351 
26352  #ifndef exprtk_disable_string_capabilities
26354  expression_node_ptr consequent,
26355  expression_node_ptr alternative) const
26356  {
26357  if ((0 == condition) || (0 == consequent))
26358  {
26359  free_node(*node_allocator_, condition);
26360  free_node(*node_allocator_, consequent);
26361  free_node(*node_allocator_, alternative);
26362 
26363  return error_node();
26364  }
26365  // Can the condition be immediately evaluated? if so optimise.
26366  else if (details::is_constant_node(condition))
26367  {
26368  // True branch
26369  if (details::is_true(condition))
26370  {
26371  free_node(*node_allocator_, condition);
26372  free_node(*node_allocator_, alternative);
26373 
26374  return consequent;
26375  }
26376  // False branch
26377  else
26378  {
26379  free_node(*node_allocator_, condition);
26380  free_node(*node_allocator_, consequent);
26381 
26382  if (alternative)
26383  return alternative;
26384  else
26385  return node_allocator_->
26386  allocate_c<details::string_literal_node<Type> >("");
26387  }
26388  }
26389  else if ((0 != consequent) && (0 != alternative))
26390  return node_allocator_->
26391  allocate<conditional_string_node_t>(condition, consequent, alternative);
26392  else
26393  return error_node();
26394  }
26395  #else
26396  inline expression_node_ptr conditional_string(expression_node_ptr,
26398  expression_node_ptr) const
26399  {
26400  return error_node();
26401  }
26402  #endif
26403 
26405  expression_node_ptr& branch,
26406  const bool brkcont = false) const
26407  {
26408  if (!brkcont && details::is_constant_node(condition))
26409  {
26410  expression_node_ptr result = error_node();
26411  if (details::is_true(condition))
26412  // Infinite loops are not allowed.
26413  result = error_node();
26414  else
26415  result = node_allocator_->allocate<details::null_node<Type> >();
26416 
26417  free_node(*node_allocator_, condition);
26418  free_node(*node_allocator_, branch);
26419 
26420  return result;
26421  }
26422  else if (details::is_null_node(condition))
26423  {
26424  free_node(*node_allocator_,condition);
26425 
26426  return branch;
26427  }
26428  else if (!brkcont)
26429  return node_allocator_->allocate<while_loop_node_t>(condition,branch);
26430  #ifndef exprtk_disable_break_continue
26431  else
26432  return node_allocator_->allocate<while_loop_bc_node_t>(condition,branch);
26433  #else
26434  return error_node();
26435  #endif
26436  }
26437 
26439  expression_node_ptr& branch,
26440  const bool brkcont = false) const
26441  {
26442  if (!brkcont && details::is_constant_node(condition))
26443  {
26444  if (
26445  details::is_true(condition) &&
26447  )
26448  {
26449  free_node(*node_allocator_,condition);
26450 
26451  return branch;
26452  }
26453 
26454  free_node(*node_allocator_, condition);
26455  free_node(*node_allocator_, branch);
26456 
26457  return error_node();
26458  }
26459  else if (details::is_null_node(condition))
26460  {
26461  free_node(*node_allocator_,condition);
26462 
26463  return branch;
26464  }
26465  else if (!brkcont)
26466  return node_allocator_->allocate<repeat_until_loop_node_t>(condition,branch);
26467  #ifndef exprtk_disable_break_continue
26468  else
26469  return node_allocator_->allocate<repeat_until_loop_bc_node_t>(condition,branch);
26470  #else
26471  return error_node();
26472  #endif
26473  }
26474 
26476  expression_node_ptr& condition,
26477  expression_node_ptr& incrementor,
26478  expression_node_ptr& loop_body,
26479  bool brkcont = false) const
26480  {
26481  if (!brkcont && details::is_constant_node(condition))
26482  {
26483  expression_node_ptr result = error_node();
26484 
26485  if (details::is_true(condition))
26486  // Infinite loops are not allowed.
26487  result = error_node();
26488  else
26489  result = node_allocator_->allocate<details::null_node<Type> >();
26490 
26491  free_node(*node_allocator_, initialiser);
26492  free_node(*node_allocator_, condition);
26493  free_node(*node_allocator_, incrementor);
26494  free_node(*node_allocator_, loop_body);
26495 
26496  return result;
26497  }
26498  else if (details::is_null_node(condition))
26499  {
26500  free_node(*node_allocator_, initialiser);
26501  free_node(*node_allocator_, condition);
26502  free_node(*node_allocator_, incrementor);
26503 
26504  return loop_body;
26505  }
26506  else if (!brkcont)
26507  return node_allocator_->allocate<for_loop_node_t>
26508  (
26509  initialiser,
26510  condition,
26511  incrementor,
26512  loop_body
26513  );
26514 
26515  #ifndef exprtk_disable_break_continue
26516  else
26517  return node_allocator_->allocate<for_loop_bc_node_t>
26518  (
26519  initialiser,
26520  condition,
26521  incrementor,
26522  loop_body
26523  );
26524  #else
26525  return error_node();
26526  #endif
26527  }
26528 
26529  template <typename Allocator,
26530  template <typename,typename> class Sequence>
26531  inline expression_node_ptr const_optimise_switch(Sequence<expression_node_ptr,Allocator>& arg_list)
26532  {
26533  expression_node_ptr result = error_node();
26534 
26535  for (std::size_t i = 0; i < (arg_list.size() / 2); ++i)
26536  {
26537  expression_node_ptr condition = arg_list[(2 * i) ];
26538  expression_node_ptr consequent = arg_list[(2 * i) + 1];
26539 
26540  if ((0 == result) && details::is_true(condition))
26541  {
26542  result = consequent;
26543  break;
26544  }
26545  }
26546 
26547  if (0 == result)
26548  {
26549  result = arg_list.back();
26550  }
26551 
26552  for (std::size_t i = 0; i < arg_list.size(); ++i)
26553  {
26554  expression_node_ptr current_expr = arg_list[i];
26555 
26556  if (current_expr && (current_expr != result))
26557  {
26558  free_node(*node_allocator_,current_expr);
26559  }
26560  }
26561 
26562  return result;
26563  }
26564 
26565  template <typename Allocator,
26566  template <typename,typename> class Sequence>
26567  inline expression_node_ptr const_optimise_mswitch(Sequence<expression_node_ptr,Allocator>& arg_list)
26568  {
26569  expression_node_ptr result = error_node();
26570 
26571  for (std::size_t i = 0; i < (arg_list.size() / 2); ++i)
26572  {
26573  expression_node_ptr condition = arg_list[(2 * i) ];
26574  expression_node_ptr consequent = arg_list[(2 * i) + 1];
26575 
26576  if (details::is_true(condition))
26577  {
26578  result = consequent;
26579  }
26580  }
26581 
26582  if (0 == result)
26583  {
26584  T zero = T(0);
26585  result = node_allocator_->allocate<literal_node_t>(zero);
26586  }
26587 
26588  for (std::size_t i = 0; i < arg_list.size(); ++i)
26589  {
26590  expression_node_ptr& current_expr = arg_list[i];
26591 
26592  if (current_expr && (current_expr != result))
26593  {
26594  free_node(*node_allocator_,current_expr);
26595  }
26596  }
26597 
26598  return result;
26599  }
26600 
26602  {
26603  typedef std::vector<expression_node_ptr> arg_list_t;
26604 
26605  #define case_stmt(N) \
26606  if (is_true(arg[(2 * N)])) { return arg[(2 * N) + 1]->value(); } \
26607 
26608  struct switch_1
26609  {
26610  static inline T process(const arg_list_t& arg)
26611  {
26612  case_stmt(0)
26613 
26614  return arg.back()->value();
26615  }
26616  };
26617 
26618  struct switch_2
26619  {
26620  static inline T process(const arg_list_t& arg)
26621  {
26622  case_stmt(0) case_stmt(1)
26623 
26624  return arg.back()->value();
26625  }
26626  };
26627 
26628  struct switch_3
26629  {
26630  static inline T process(const arg_list_t& arg)
26631  {
26632  case_stmt(0) case_stmt(1)
26633  case_stmt(2)
26634 
26635  return arg.back()->value();
26636  }
26637  };
26638 
26639  struct switch_4
26640  {
26641  static inline T process(const arg_list_t& arg)
26642  {
26643  case_stmt(0) case_stmt(1)
26644  case_stmt(2) case_stmt(3)
26645 
26646  return arg.back()->value();
26647  }
26648  };
26649 
26650  struct switch_5
26651  {
26652  static inline T process(const arg_list_t& arg)
26653  {
26654  case_stmt(0) case_stmt(1)
26655  case_stmt(2) case_stmt(3)
26656  case_stmt(4)
26657 
26658  return arg.back()->value();
26659  }
26660  };
26661 
26662  struct switch_6
26663  {
26664  static inline T process(const arg_list_t& arg)
26665  {
26666  case_stmt(0) case_stmt(1)
26667  case_stmt(2) case_stmt(3)
26668  case_stmt(4) case_stmt(5)
26669 
26670  return arg.back()->value();
26671  }
26672  };
26673 
26674  struct switch_7
26675  {
26676  static inline T process(const arg_list_t& arg)
26677  {
26678  case_stmt(0) case_stmt(1)
26679  case_stmt(2) case_stmt(3)
26680  case_stmt(4) case_stmt(5)
26681  case_stmt(6)
26682 
26683  return arg.back()->value();
26684  }
26685  };
26686 
26687  #undef case_stmt
26688  };
26689 
26690  template <typename Allocator,
26691  template <typename,typename> class Sequence>
26692  inline expression_node_ptr switch_statement(Sequence<expression_node_ptr,Allocator>& arg_list)
26693  {
26694  if (arg_list.empty())
26695  return error_node();
26696  else if (
26697  !all_nodes_valid(arg_list) ||
26698  (arg_list.size() < 3) ||
26699  ((arg_list.size() % 2) != 1)
26700  )
26701  {
26702  details::free_all_nodes(*node_allocator_,arg_list);
26703 
26704  return error_node();
26705  }
26706  else if (is_constant_foldable(arg_list))
26707  return const_optimise_switch(arg_list);
26708 
26709  switch ((arg_list.size() - 1) / 2)
26710  {
26711  #define case_stmt(N) \
26712  case N : \
26713  return node_allocator_-> \
26714  allocate<details::switch_n_node \
26715  <Type,typename switch_nodes::switch_##N> >(arg_list); \
26716 
26717  case_stmt(1)
26718  case_stmt(2)
26719  case_stmt(3)
26720  case_stmt(4)
26721  case_stmt(5)
26722  case_stmt(6)
26723  case_stmt(7)
26724  #undef case_stmt
26725 
26726  default : return node_allocator_->allocate<details::switch_node<Type> >(arg_list);
26727  }
26728  }
26729 
26730  template <typename Allocator,
26731  template <typename,typename> class Sequence>
26732  inline expression_node_ptr multi_switch_statement(Sequence<expression_node_ptr,Allocator>& arg_list)
26733  {
26734  if (!all_nodes_valid(arg_list))
26735  {
26736  details::free_all_nodes(*node_allocator_,arg_list);
26737 
26738  return error_node();
26739  }
26740  else if (is_constant_foldable(arg_list))
26741  return const_optimise_mswitch(arg_list);
26742  else
26743  return node_allocator_->allocate<details::multi_switch_node<Type> >(arg_list);
26744  }
26745 
26746  #define unary_opr_switch_statements \
26747  case_stmt(details:: e_abs, details:: abs_op) \
26748  case_stmt(details:: e_acos, details:: acos_op) \
26749  case_stmt(details::e_acosh, details::acosh_op) \
26750  case_stmt(details:: e_asin, details:: asin_op) \
26751  case_stmt(details::e_asinh, details::asinh_op) \
26752  case_stmt(details:: e_atan, details:: atan_op) \
26753  case_stmt(details::e_atanh, details::atanh_op) \
26754  case_stmt(details:: e_ceil, details:: ceil_op) \
26755  case_stmt(details:: e_cos, details:: cos_op) \
26756  case_stmt(details:: e_cosh, details:: cosh_op) \
26757  case_stmt(details:: e_exp, details:: exp_op) \
26758  case_stmt(details::e_expm1, details::expm1_op) \
26759  case_stmt(details::e_floor, details::floor_op) \
26760  case_stmt(details:: e_log, details:: log_op) \
26761  case_stmt(details::e_log10, details::log10_op) \
26762  case_stmt(details:: e_log2, details:: log2_op) \
26763  case_stmt(details::e_log1p, details::log1p_op) \
26764  case_stmt(details:: e_neg, details:: neg_op) \
26765  case_stmt(details:: e_pos, details:: pos_op) \
26766  case_stmt(details::e_round, details::round_op) \
26767  case_stmt(details:: e_sin, details:: sin_op) \
26768  case_stmt(details:: e_sinc, details:: sinc_op) \
26769  case_stmt(details:: e_sinh, details:: sinh_op) \
26770  case_stmt(details:: e_sqrt, details:: sqrt_op) \
26771  case_stmt(details:: e_tan, details:: tan_op) \
26772  case_stmt(details:: e_tanh, details:: tanh_op) \
26773  case_stmt(details:: e_cot, details:: cot_op) \
26774  case_stmt(details:: e_sec, details:: sec_op) \
26775  case_stmt(details:: e_csc, details:: csc_op) \
26776  case_stmt(details:: e_r2d, details:: r2d_op) \
26777  case_stmt(details:: e_d2r, details:: d2r_op) \
26778  case_stmt(details:: e_d2g, details:: d2g_op) \
26779  case_stmt(details:: e_g2d, details:: g2d_op) \
26780  case_stmt(details:: e_notl, details:: notl_op) \
26781  case_stmt(details:: e_sgn, details:: sgn_op) \
26782  case_stmt(details:: e_erf, details:: erf_op) \
26783  case_stmt(details:: e_erfc, details:: erfc_op) \
26784  case_stmt(details:: e_ncdf, details:: ncdf_op) \
26785  case_stmt(details:: e_frac, details:: frac_op) \
26786  case_stmt(details::e_trunc, details::trunc_op) \
26787 
26789  expression_node_ptr (&branch)[1])
26790  {
26791  T& v = static_cast<details::variable_node<T>*>(branch[0])->ref();
26792 
26793  switch (operation)
26794  {
26795  #define case_stmt(op0,op1) \
26796  case op0 : return node_allocator_-> \
26797  allocate<typename details::unary_variable_node<Type,op1<Type> > >(v); \
26798 
26800  #undef case_stmt
26801  default : return error_node();
26802  }
26803  }
26804 
26806  expression_node_ptr (&branch)[1])
26807  {
26808  switch (operation)
26809  {
26810  #define case_stmt(op0,op1) \
26811  case op0 : return node_allocator_-> \
26812  allocate<typename details::unary_vector_node<Type,op1<Type> > > \
26813  (operation, branch[0]); \
26814 
26816  #undef case_stmt
26817  default : return error_node();
26818  }
26819  }
26820 
26822  expression_node_ptr (&branch)[1])
26823  {
26824  switch (operation)
26825  {
26826  #define case_stmt(op0,op1) \
26827  case op0 : return node_allocator_-> \
26828  allocate<typename details::unary_branch_node<Type,op1<Type> > >(branch[0]); \
26829 
26831  #undef case_stmt
26832  default : return error_node();
26833  }
26834  }
26835 
26837  expression_node_ptr (&branch)[3])
26838  {
26839  expression_node_ptr temp_node = error_node();
26840 
26841  switch (operation)
26842  {
26843  #define case_stmt(op) \
26844  case details::e_sf##op : temp_node = node_allocator_-> \
26845  allocate<details::sf3_node<Type,details::sf##op##_op<Type> > > \
26846  (operation, branch); \
26847  break; \
26848 
26849  case_stmt(00) case_stmt(01) case_stmt(02) case_stmt(03)
26850  case_stmt(04) case_stmt(05) case_stmt(06) case_stmt(07)
26851  case_stmt(08) case_stmt(09) case_stmt(10) case_stmt(11)
26852  case_stmt(12) case_stmt(13) case_stmt(14) case_stmt(15)
26853  case_stmt(16) case_stmt(17) case_stmt(18) case_stmt(19)
26854  case_stmt(20) case_stmt(21) case_stmt(22) case_stmt(23)
26855  case_stmt(24) case_stmt(25) case_stmt(26) case_stmt(27)
26856  case_stmt(28) case_stmt(29) case_stmt(30) case_stmt(31)
26857  case_stmt(32) case_stmt(33) case_stmt(34) case_stmt(35)
26858  case_stmt(36) case_stmt(37) case_stmt(38) case_stmt(39)
26859  case_stmt(40) case_stmt(41) case_stmt(42) case_stmt(43)
26860  case_stmt(44) case_stmt(45) case_stmt(46) case_stmt(47)
26861  #undef case_stmt
26862  default : return error_node();
26863  }
26864 
26865  const T v = temp_node->value();
26866 
26867  details::free_node(*node_allocator_,temp_node);
26868 
26869  return node_allocator_->allocate<literal_node_t>(v);
26870  }
26871 
26873  {
26874  typedef details::variable_node<Type>* variable_ptr;
26875 
26876  const Type& v0 = static_cast<variable_ptr>(branch[0])->ref();
26877  const Type& v1 = static_cast<variable_ptr>(branch[1])->ref();
26878  const Type& v2 = static_cast<variable_ptr>(branch[2])->ref();
26879 
26880  switch (operation)
26881  {
26882  #define case_stmt(op) \
26883  case details::e_sf##op : return node_allocator_-> \
26884  allocate_rrr<details::sf3_var_node<Type,details::sf##op##_op<Type> > > \
26885  (v0, v1, v2); \
26886 
26887  case_stmt(00) case_stmt(01) case_stmt(02) case_stmt(03)
26888  case_stmt(04) case_stmt(05) case_stmt(06) case_stmt(07)
26889  case_stmt(08) case_stmt(09) case_stmt(10) case_stmt(11)
26890  case_stmt(12) case_stmt(13) case_stmt(14) case_stmt(15)
26891  case_stmt(16) case_stmt(17) case_stmt(18) case_stmt(19)
26892  case_stmt(20) case_stmt(21) case_stmt(22) case_stmt(23)
26893  case_stmt(24) case_stmt(25) case_stmt(26) case_stmt(27)
26894  case_stmt(28) case_stmt(29) case_stmt(30) case_stmt(31)
26895  case_stmt(32) case_stmt(33) case_stmt(34) case_stmt(35)
26896  case_stmt(36) case_stmt(37) case_stmt(38) case_stmt(39)
26897  case_stmt(40) case_stmt(41) case_stmt(42) case_stmt(43)
26898  case_stmt(44) case_stmt(45) case_stmt(46) case_stmt(47)
26899  #undef case_stmt
26900  default : return error_node();
26901  }
26902  }
26903 
26905  {
26906  if (!all_nodes_valid(branch))
26907  return error_node();
26908  else if (is_constant_foldable(branch))
26909  return const_optimise_sf3(operation,branch);
26910  else if (all_nodes_variables(branch))
26911  return varnode_optimise_sf3(operation,branch);
26912  else
26913  {
26914  switch (operation)
26915  {
26916  #define case_stmt(op) \
26917  case details::e_sf##op : return node_allocator_-> \
26918  allocate<details::sf3_node<Type,details::sf##op##_op<Type> > > \
26919  (operation, branch); \
26920 
26921  case_stmt(00) case_stmt(01) case_stmt(02) case_stmt(03)
26922  case_stmt(04) case_stmt(05) case_stmt(06) case_stmt(07)
26923  case_stmt(08) case_stmt(09) case_stmt(10) case_stmt(11)
26924  case_stmt(12) case_stmt(13) case_stmt(14) case_stmt(15)
26925  case_stmt(16) case_stmt(17) case_stmt(18) case_stmt(19)
26926  case_stmt(20) case_stmt(21) case_stmt(22) case_stmt(23)
26927  case_stmt(24) case_stmt(25) case_stmt(26) case_stmt(27)
26928  case_stmt(28) case_stmt(29) case_stmt(30) case_stmt(31)
26929  case_stmt(32) case_stmt(33) case_stmt(34) case_stmt(35)
26930  case_stmt(36) case_stmt(37) case_stmt(38) case_stmt(39)
26931  case_stmt(40) case_stmt(41) case_stmt(42) case_stmt(43)
26932  case_stmt(44) case_stmt(45) case_stmt(46) case_stmt(47)
26933  #undef case_stmt
26934  default : return error_node();
26935  }
26936  }
26937  }
26938 
26940  {
26941  expression_node_ptr temp_node = error_node();
26942 
26943  switch (operation)
26944  {
26945  #define case_stmt(op) \
26946  case details::e_sf##op : temp_node = node_allocator_-> \
26947  allocate<details::sf4_node<Type,details::sf##op##_op<Type> > > \
26948  (operation, branch); \
26949  break; \
26950 
26951  case_stmt(48) case_stmt(49) case_stmt(50) case_stmt(51)
26952  case_stmt(52) case_stmt(53) case_stmt(54) case_stmt(55)
26953  case_stmt(56) case_stmt(57) case_stmt(58) case_stmt(59)
26954  case_stmt(60) case_stmt(61) case_stmt(62) case_stmt(63)
26955  case_stmt(64) case_stmt(65) case_stmt(66) case_stmt(67)
26956  case_stmt(68) case_stmt(69) case_stmt(70) case_stmt(71)
26957  case_stmt(72) case_stmt(73) case_stmt(74) case_stmt(75)
26958  case_stmt(76) case_stmt(77) case_stmt(78) case_stmt(79)
26959  case_stmt(80) case_stmt(81) case_stmt(82) case_stmt(83)
26960  case_stmt(84) case_stmt(85) case_stmt(86) case_stmt(87)
26961  case_stmt(88) case_stmt(89) case_stmt(90) case_stmt(91)
26962  case_stmt(92) case_stmt(93) case_stmt(94) case_stmt(95)
26963  case_stmt(96) case_stmt(97) case_stmt(98) case_stmt(99)
26964  #undef case_stmt
26965  default : return error_node();
26966  }
26967 
26968  const T v = temp_node->value();
26969 
26970  details::free_node(*node_allocator_,temp_node);
26971 
26972  return node_allocator_->allocate<literal_node_t>(v);
26973  }
26974 
26976  {
26977  typedef details::variable_node<Type>* variable_ptr;
26978 
26979  const Type& v0 = static_cast<variable_ptr>(branch[0])->ref();
26980  const Type& v1 = static_cast<variable_ptr>(branch[1])->ref();
26981  const Type& v2 = static_cast<variable_ptr>(branch[2])->ref();
26982  const Type& v3 = static_cast<variable_ptr>(branch[3])->ref();
26983 
26984  switch (operation)
26985  {
26986  #define case_stmt(op) \
26987  case details::e_sf##op : return node_allocator_-> \
26988  allocate_rrrr<details::sf4_var_node<Type,details::sf##op##_op<Type> > > \
26989  (v0, v1, v2, v3); \
26990 
26991  case_stmt(48) case_stmt(49) case_stmt(50) case_stmt(51)
26992  case_stmt(52) case_stmt(53) case_stmt(54) case_stmt(55)
26993  case_stmt(56) case_stmt(57) case_stmt(58) case_stmt(59)
26994  case_stmt(60) case_stmt(61) case_stmt(62) case_stmt(63)
26995  case_stmt(64) case_stmt(65) case_stmt(66) case_stmt(67)
26996  case_stmt(68) case_stmt(69) case_stmt(70) case_stmt(71)
26997  case_stmt(72) case_stmt(73) case_stmt(74) case_stmt(75)
26998  case_stmt(76) case_stmt(77) case_stmt(78) case_stmt(79)
26999  case_stmt(80) case_stmt(81) case_stmt(82) case_stmt(83)
27000  case_stmt(84) case_stmt(85) case_stmt(86) case_stmt(87)
27001  case_stmt(88) case_stmt(89) case_stmt(90) case_stmt(91)
27002  case_stmt(92) case_stmt(93) case_stmt(94) case_stmt(95)
27003  case_stmt(96) case_stmt(97) case_stmt(98) case_stmt(99)
27004  #undef case_stmt
27005  default : return error_node();
27006  }
27007  }
27008 
27010  {
27011  if (!all_nodes_valid(branch))
27012  return error_node();
27013  else if (is_constant_foldable(branch))
27014  return const_optimise_sf4(operation,branch);
27015  else if (all_nodes_variables(branch))
27016  return varnode_optimise_sf4(operation,branch);
27017  switch (operation)
27018  {
27019  #define case_stmt(op) \
27020  case details::e_sf##op : return node_allocator_-> \
27021  allocate<details::sf4_node<Type,details::sf##op##_op<Type> > > \
27022  (operation, branch); \
27023 
27024  case_stmt(48) case_stmt(49) case_stmt(50) case_stmt(51)
27025  case_stmt(52) case_stmt(53) case_stmt(54) case_stmt(55)
27026  case_stmt(56) case_stmt(57) case_stmt(58) case_stmt(59)
27027  case_stmt(60) case_stmt(61) case_stmt(62) case_stmt(63)
27028  case_stmt(64) case_stmt(65) case_stmt(66) case_stmt(67)
27029  case_stmt(68) case_stmt(69) case_stmt(70) case_stmt(71)
27030  case_stmt(72) case_stmt(73) case_stmt(74) case_stmt(75)
27031  case_stmt(76) case_stmt(77) case_stmt(78) case_stmt(79)
27032  case_stmt(80) case_stmt(81) case_stmt(82) case_stmt(83)
27033  case_stmt(84) case_stmt(85) case_stmt(86) case_stmt(87)
27034  case_stmt(88) case_stmt(89) case_stmt(90) case_stmt(91)
27035  case_stmt(92) case_stmt(93) case_stmt(94) case_stmt(95)
27036  case_stmt(96) case_stmt(97) case_stmt(98) case_stmt(99)
27037  #undef case_stmt
27038  default : return error_node();
27039  }
27040  }
27041 
27042  template <typename Allocator,
27043  template <typename,typename> class Sequence>
27044  inline expression_node_ptr const_optimise_varargfunc(const details::operator_type& operation, Sequence<expression_node_ptr,Allocator>& arg_list)
27045  {
27046  expression_node_ptr temp_node = error_node();
27047 
27048  switch (operation)
27049  {
27050  #define case_stmt(op0,op1) \
27051  case op0 : temp_node = node_allocator_-> \
27052  allocate<details::vararg_node<Type,op1<Type> > > \
27053  (arg_list); \
27054  break; \
27055 
27064  #undef case_stmt
27065  default : return error_node();
27066  }
27067 
27068  const T v = temp_node->value();
27069 
27070  details::free_node(*node_allocator_,temp_node);
27071 
27072  return node_allocator_->allocate<literal_node_t>(v);
27073  }
27074 
27076  {
27077  return (
27078  (details::e_sum == operation) ||
27079  (details::e_prod == operation) ||
27080  (details::e_avg == operation) ||
27081  (details::e_min == operation) ||
27082  (details::e_max == operation)
27083  );
27084  }
27085 
27086  template <typename Allocator,
27087  template <typename,typename> class Sequence>
27088  inline expression_node_ptr varnode_optimise_varargfunc(const details::operator_type& operation, Sequence<expression_node_ptr,Allocator>& arg_list)
27089  {
27090  switch (operation)
27091  {
27092  #define case_stmt(op0,op1) \
27093  case op0 : return node_allocator_-> \
27094  allocate<details::vararg_varnode<Type,op1<Type> > >(arg_list); \
27095 
27104  #undef case_stmt
27105  default : return error_node();
27106  }
27107  }
27108 
27109  template <typename Allocator,
27110  template <typename,typename> class Sequence>
27111  inline expression_node_ptr vectorize_func(const details::operator_type& operation, Sequence<expression_node_ptr,Allocator>& arg_list)
27112  {
27113  if (1 == arg_list.size())
27114  {
27115  switch (operation)
27116  {
27117  #define case_stmt(op0,op1) \
27118  case op0 : return node_allocator_-> \
27119  allocate<details::vectorize_node<Type,op1<Type> > >(arg_list[0]); \
27120 
27126  #undef case_stmt
27127  default : return error_node();
27128  }
27129  }
27130  else
27131  return error_node();
27132  }
27133 
27134  template <typename Allocator,
27135  template <typename,typename> class Sequence>
27136  inline expression_node_ptr vararg_function(const details::operator_type& operation, Sequence<expression_node_ptr,Allocator>& arg_list)
27137  {
27138  if (!all_nodes_valid(arg_list))
27139  {
27140  details::free_all_nodes(*node_allocator_,arg_list);
27141 
27142  return error_node();
27143  }
27144  else if (is_constant_foldable(arg_list))
27145  return const_optimise_varargfunc(operation,arg_list);
27146  else if ((arg_list.size() == 1) && details::is_ivector_node(arg_list[0]))
27147  return vectorize_func(operation,arg_list);
27148  else if ((arg_list.size() == 1) && special_one_parameter_vararg(operation))
27149  return arg_list[0];
27150  else if (all_nodes_variables(arg_list))
27151  return varnode_optimise_varargfunc(operation,arg_list);
27152 
27153  #ifndef exprtk_disable_string_capabilities
27154  if (details::e_smulti == operation)
27155  {
27156  return node_allocator_->
27157  allocate<details::str_vararg_node<Type,details::vararg_multi_op<Type> > >(arg_list);
27158  }
27159  else
27160  #endif
27161  {
27162  switch (operation)
27163  {
27164  #define case_stmt(op0,op1) \
27165  case op0 : return node_allocator_-> \
27166  allocate<details::vararg_node<Type,op1<Type> > >(arg_list); \
27167 
27176  #undef case_stmt
27177  default : return error_node();
27178  }
27179  }
27180  }
27181 
27182  template <std::size_t N>
27184  {
27185  typedef typename details::function_N_node<T,ifunction_t,N> function_N_node_t;
27186  expression_node_ptr result = synthesize_expression<function_N_node_t,N>(f,b);
27187 
27188  if (0 == result)
27189  return error_node();
27190  else
27191  {
27192  // Can the function call be completely optimised?
27193  if (details::is_constant_node(result))
27194  return result;
27195  else if (!all_nodes_valid(b))
27196  return error_node();
27197  else if (N != f->param_count)
27198  {
27199  details::free_all_nodes(*node_allocator_,b);
27200 
27201  return error_node();
27202  }
27203 
27204  function_N_node_t* func_node_ptr = static_cast<function_N_node_t*>(result);
27205 
27206  if (func_node_ptr->init_branches(b))
27207  return result;
27208  else
27209  {
27210  details::free_all_nodes(*node_allocator_,b);
27211 
27212  return error_node();
27213  }
27214  }
27215  }
27216 
27217  inline expression_node_ptr function(ifunction_t* f)
27218  {
27219  typedef typename details::function_N_node<Type,ifunction_t,0> function_N_node_t;
27220  return node_allocator_->allocate<function_N_node_t>(f);
27221  }
27222 
27224  std::vector<expression_node_ptr>& arg_list)
27225  {
27226  if (!all_nodes_valid(arg_list))
27227  {
27228  details::free_all_nodes(*node_allocator_,arg_list);
27229 
27230  return error_node();
27231  }
27232 
27234 
27235  expression_node_ptr result = node_allocator_->allocate<alloc_type>(vaf,arg_list);
27236 
27237  if (
27238  !arg_list.empty() &&
27239  !vaf->has_side_effects() &&
27240  is_constant_foldable(arg_list)
27241  )
27242  {
27243  const Type v = result->value();
27244  details::free_node(*node_allocator_,result);
27245  result = node_allocator_->allocate<literal_node_t>(v);
27246  }
27247 
27248  parser_->state_.activate_side_effect("vararg_function_call()");
27249 
27250  return result;
27251  }
27252 
27254  std::vector<expression_node_ptr>& arg_list,
27255  const std::size_t& param_seq_index = std::numeric_limits<std::size_t>::max())
27256  {
27257  if (!all_nodes_valid(arg_list))
27258  {
27259  details::free_all_nodes(*node_allocator_,arg_list);
27260  return error_node();
27261  }
27262 
27265 
27266  const std::size_t no_psi = std::numeric_limits<std::size_t>::max();
27267 
27268  expression_node_ptr result = error_node();
27269 
27270  if (no_psi == param_seq_index)
27271  result = node_allocator_->allocate<alloc_type1>(arg_list,gf);
27272  else
27273  result = node_allocator_->allocate<alloc_type2>(gf, param_seq_index, arg_list);
27274 
27275  alloc_type1* genfunc_node_ptr = static_cast<alloc_type1*>(result);
27276 
27277  if (
27278  !arg_list.empty() &&
27279  !gf->has_side_effects() &&
27280  parser_->state_.type_check_enabled &&
27281  is_constant_foldable(arg_list)
27282  )
27283  {
27284  genfunc_node_ptr->init_branches();
27285 
27286  const Type v = result->value();
27287 
27288  details::free_node(*node_allocator_,result);
27289 
27290  return node_allocator_->allocate<literal_node_t>(v);
27291  }
27292  else if (genfunc_node_ptr->init_branches())
27293  {
27294  parser_->state_.activate_side_effect("generic_function_call()");
27295 
27296  return result;
27297  }
27298  else
27299  {
27300  details::free_node(*node_allocator_, result);
27301  details::free_all_nodes(*node_allocator_, arg_list);
27302 
27303  return error_node();
27304  }
27305  }
27306 
27307  #ifndef exprtk_disable_string_capabilities
27309  std::vector<expression_node_ptr>& arg_list,
27310  const std::size_t& param_seq_index = std::numeric_limits<std::size_t>::max())
27311  {
27312  if (!all_nodes_valid(arg_list))
27313  {
27314  details::free_all_nodes(*node_allocator_,arg_list);
27315  return error_node();
27316  }
27317 
27320 
27321  const std::size_t no_psi = std::numeric_limits<std::size_t>::max();
27322 
27323  expression_node_ptr result = error_node();
27324 
27325  if (no_psi == param_seq_index)
27326  result = node_allocator_->allocate<alloc_type1>(gf,arg_list);
27327  else
27328  result = node_allocator_->allocate<alloc_type2>(gf, param_seq_index, arg_list);
27329 
27330  alloc_type1* strfunc_node_ptr = static_cast<alloc_type1*>(result);
27331 
27332  if (
27333  !arg_list.empty() &&
27334  !gf->has_side_effects() &&
27335  is_constant_foldable(arg_list)
27336  )
27337  {
27338  strfunc_node_ptr->init_branches();
27339 
27340  const Type v = result->value();
27341 
27342  details::free_node(*node_allocator_,result);
27343 
27344  return node_allocator_->allocate<literal_node_t>(v);
27345  }
27346  else if (strfunc_node_ptr->init_branches())
27347  {
27348  parser_->state_.activate_side_effect("string_function_call()");
27349 
27350  return result;
27351  }
27352  else
27353  {
27354  details::free_node (*node_allocator_,result );
27355  details::free_all_nodes(*node_allocator_,arg_list);
27356 
27357  return error_node();
27358  }
27359  }
27360  #endif
27361 
27362  #ifndef exprtk_disable_return_statement
27363  inline expression_node_ptr return_call(std::vector<expression_node_ptr>& arg_list)
27364  {
27365  if (!all_nodes_valid(arg_list))
27366  {
27367  details::free_all_nodes(*node_allocator_,arg_list);
27368  return error_node();
27369  }
27370 
27371  typedef details::return_node<Type> alloc_type;
27372 
27373  expression_node_ptr result = node_allocator_->
27374  allocate_rr<alloc_type>(arg_list,parser_->results_ctx());
27375 
27376  alloc_type* return_node_ptr = static_cast<alloc_type*>(result);
27377 
27378  if (return_node_ptr->init_branches())
27379  {
27380  parser_->state_.activate_side_effect("return_call()");
27381 
27382  return result;
27383  }
27384  else
27385  {
27386  details::free_node (*node_allocator_,result );
27387  details::free_all_nodes(*node_allocator_,arg_list);
27388 
27389  return error_node();
27390  }
27391  }
27392 
27394  results_context_t* rc,
27395  bool*& return_invoked)
27396  {
27397  typedef details::return_envelope_node<Type> alloc_type;
27398 
27399  expression_node_ptr result = node_allocator_->
27400  allocate_cr<alloc_type>(body,(*rc));
27401 
27402  return_invoked = static_cast<alloc_type*>(result)->retinvk_ptr();
27403 
27404  return result;
27405  }
27406  #else
27407  inline expression_node_ptr return_call(std::vector<expression_node_ptr>&)
27408  {
27409  return error_node();
27410  }
27411 
27412  inline expression_node_ptr return_envelope(expression_node_ptr,
27413  results_context_t*,
27414  bool*&)
27415  {
27416  return error_node();
27417  }
27418  #endif
27419 
27420  inline expression_node_ptr vector_element(const std::string& symbol,
27421  vector_holder_ptr vector_base,
27422  expression_node_ptr index)
27423  {
27424  expression_node_ptr result = error_node();
27425 
27426  if (details::is_constant_node(index))
27427  {
27428  std::size_t i = static_cast<std::size_t>(details::numeric::to_int64(index->value()));
27429 
27430  details::free_node(*node_allocator_,index);
27431 
27432  if (vector_base->rebaseable())
27433  {
27434  return node_allocator_->allocate<rebasevector_celem_node_t>(i,vector_base);
27435  }
27436 
27437  scope_element& se = parser_->sem_.get_element(symbol,i);
27438 
27439  if (se.index == i)
27440  {
27441  result = se.var_node;
27442  }
27443  else
27444  {
27445  scope_element nse;
27446  nse.name = symbol;
27447  nse.active = true;
27448  nse.ref_count = 1;
27449  nse.type = scope_element::e_vecelem;
27450  nse.index = i;
27451  nse.depth = parser_->state_.scope_depth;
27452  nse.data = 0;
27453  nse.var_node = node_allocator_->allocate<variable_node_t>((*(*vector_base)[i]));
27454 
27455  if (!parser_->sem_.add_element(nse))
27456  {
27457  parser_->set_synthesis_error("Failed to add new local vector element to SEM [1]");
27458 
27459  parser_->sem_.free_element(nse);
27460 
27461  result = error_node();
27462  }
27463 
27464  exprtk_debug(("vector_element() - INFO - Added new local vector element: %s\n",nse.name.c_str()));
27465 
27466  parser_->state_.activate_side_effect("vector_element()");
27467 
27468  result = nse.var_node;
27469  }
27470  }
27471  else if (vector_base->rebaseable())
27472  result = node_allocator_->allocate<rebasevector_elem_node_t>(index,vector_base);
27473  else
27474  result = node_allocator_->allocate<vector_elem_node_t>(index,vector_base);
27475 
27476  return result;
27477  }
27478 
27479  private:
27480 
27481  template <std::size_t N, typename NodePtr>
27482  inline bool is_constant_foldable(NodePtr (&b)[N]) const
27483  {
27484  for (std::size_t i = 0; i < N; ++i)
27485  {
27486  if (0 == b[i])
27487  return false;
27488  else if (!details::is_constant_node(b[i]))
27489  return false;
27490  }
27491 
27492  return true;
27493  }
27494 
27495  template <typename NodePtr,
27496  typename Allocator,
27497  template <typename,typename> class Sequence>
27498  inline bool is_constant_foldable(const Sequence<NodePtr,Allocator>& b) const
27499  {
27500  for (std::size_t i = 0; i < b.size(); ++i)
27501  {
27502  if (0 == b[i])
27503  return false;
27504  else if (!details::is_constant_node(b[i]))
27505  return false;
27506  }
27507 
27508  return true;
27509  }
27510 
27512  {
27513  parser_->state_.activate_side_effect("lodge_assignment()");
27514 
27515  if (!parser_->dec_.collect_assignments())
27516  return;
27517 
27518  std::string symbol_name;
27519 
27520  switch (cst)
27521  {
27522  case e_st_variable : symbol_name = parser_->symtab_store_
27523  .get_variable_name(node);
27524  break;
27525 
27526  #ifndef exprtk_disable_string_capabilities
27527  case e_st_string : symbol_name = parser_->symtab_store_
27528  .get_stringvar_name(node);
27529  break;
27530  #endif
27531 
27532  case e_st_vector : {
27533  typedef details::vector_holder<T> vector_holder_t;
27534 
27535  vector_holder_t& vh = static_cast<vector_node_t*>(node)->vec_holder();
27536 
27537  symbol_name = parser_->symtab_store_.get_vector_name(&vh);
27538  }
27539  break;
27540 
27541  case e_st_vecelem : {
27542  typedef details::vector_holder<T> vector_holder_t;
27543 
27544  vector_holder_t& vh = static_cast<vector_elem_node_t*>(node)->vec_holder();
27545 
27546  symbol_name = parser_->symtab_store_.get_vector_name(&vh);
27547 
27548  cst = e_st_vector;
27549  }
27550  break;
27551 
27552  default : return;
27553  }
27554 
27555  if (!symbol_name.empty())
27556  {
27557  parser_->dec_.add_assignment(symbol_name,cst);
27558  }
27559  }
27560 
27562  {
27563  if (details::is_variable_node(branch[0]))
27564  {
27565  lodge_assignment(e_st_variable,branch[0]);
27566 
27567  return synthesize_expression<assignment_node_t,2>(operation,branch);
27568  }
27569  else if (details::is_vector_elem_node(branch[0]))
27570  {
27571  lodge_assignment(e_st_vecelem,branch[0]);
27572 
27573  return synthesize_expression<assignment_vec_elem_node_t, 2>(operation, branch);
27574  }
27575  else if (details::is_rebasevector_elem_node(branch[0]))
27576  {
27577  lodge_assignment(e_st_vecelem,branch[0]);
27578 
27579  return synthesize_expression<assignment_rebasevec_elem_node_t, 2>(operation, branch);
27580  }
27581  else if (details::is_rebasevector_celem_node(branch[0]))
27582  {
27583  lodge_assignment(e_st_vecelem,branch[0]);
27584 
27585  return synthesize_expression<assignment_rebasevec_celem_node_t, 2>(operation, branch);
27586  }
27587  #ifndef exprtk_disable_string_capabilities
27588  else if (details::is_string_node(branch[0]))
27589  {
27590  lodge_assignment(e_st_string,branch[0]);
27591 
27592  return synthesize_expression<assignment_string_node_t,2>(operation, branch);
27593  }
27594  else if (details::is_string_range_node(branch[0]))
27595  {
27596  lodge_assignment(e_st_string,branch[0]);
27597 
27598  return synthesize_expression<assignment_string_range_node_t,2>(operation, branch);
27599  }
27600  #endif
27601  else if (details::is_vector_node(branch[0]))
27602  {
27603  lodge_assignment(e_st_vector,branch[0]);
27604 
27605  if (details::is_ivector_node(branch[1]))
27606  return synthesize_expression<assignment_vecvec_node_t,2>(operation, branch);
27607  else
27608  return synthesize_expression<assignment_vec_node_t,2>(operation, branch);
27609  }
27610  else
27611  {
27612  parser_->set_synthesis_error("Invalid assignment operation.[1]");
27613 
27614  return error_node();
27615  }
27616  }
27617 
27619  expression_node_ptr (&branch)[2])
27620  {
27621  if (details::is_variable_node(branch[0]))
27622  {
27623  lodge_assignment(e_st_variable,branch[0]);
27624 
27625  switch (operation)
27626  {
27627  #define case_stmt(op0,op1) \
27628  case op0 : return node_allocator_-> \
27629  template allocate_rrr<typename details::assignment_op_node<Type,op1<Type> > > \
27630  (operation, branch[0], branch[1]); \
27631 
27637  #undef case_stmt
27638  default : return error_node();
27639  }
27640  }
27641  else if (details::is_vector_elem_node(branch[0]))
27642  {
27643  lodge_assignment(e_st_vecelem,branch[0]);
27644 
27645  switch (operation)
27646  {
27647  #define case_stmt(op0,op1) \
27648  case op0 : return node_allocator_-> \
27649  template allocate_rrr<typename details::assignment_vec_elem_op_node<Type,op1<Type> > > \
27650  (operation, branch[0], branch[1]); \
27651 
27657  #undef case_stmt
27658  default : return error_node();
27659  }
27660  }
27661  else if (details::is_rebasevector_elem_node(branch[0]))
27662  {
27663  lodge_assignment(e_st_vecelem,branch[0]);
27664 
27665  switch (operation)
27666  {
27667  #define case_stmt(op0,op1) \
27668  case op0 : return node_allocator_-> \
27669  template allocate_rrr<typename details::assignment_rebasevec_elem_op_node<Type,op1<Type> > > \
27670  (operation, branch[0], branch[1]); \
27671 
27677  #undef case_stmt
27678  default : return error_node();
27679  }
27680  }
27681  else if (details::is_rebasevector_celem_node(branch[0]))
27682  {
27683  lodge_assignment(e_st_vecelem,branch[0]);
27684 
27685  switch (operation)
27686  {
27687  #define case_stmt(op0,op1) \
27688  case op0 : return node_allocator_-> \
27689  template allocate_rrr<typename details::assignment_rebasevec_celem_op_node<Type,op1<Type> > > \
27690  (operation, branch[0], branch[1]); \
27691 
27697  #undef case_stmt
27698  default : return error_node();
27699  }
27700  }
27701  else if (details::is_vector_node(branch[0]))
27702  {
27703  lodge_assignment(e_st_vector,branch[0]);
27704 
27705  if (details::is_ivector_node(branch[1]))
27706  {
27707  switch (operation)
27708  {
27709  #define case_stmt(op0,op1) \
27710  case op0 : return node_allocator_-> \
27711  template allocate_rrr<typename details::assignment_vecvec_op_node<Type,op1<Type> > > \
27712  (operation, branch[0], branch[1]); \
27713 
27719  #undef case_stmt
27720  default : return error_node();
27721  }
27722  }
27723  else
27724  {
27725  switch (operation)
27726  {
27727  #define case_stmt(op0,op1) \
27728  case op0 : return node_allocator_-> \
27729  template allocate_rrr<typename details::assignment_vec_op_node<Type,op1<Type> > > \
27730  (operation, branch[0], branch[1]); \
27731 
27737  #undef case_stmt
27738  default : return error_node();
27739  }
27740  }
27741  }
27742  #ifndef exprtk_disable_string_capabilities
27743  else if (
27744  (details::e_addass == operation) &&
27745  details::is_string_node(branch[0])
27746  )
27747  {
27749 
27750  lodge_assignment(e_st_string,branch[0]);
27751 
27752  return synthesize_expression<addass_t,2>(operation,branch);
27753  }
27754  #endif
27755  else
27756  {
27757  parser_->set_synthesis_error("Invalid assignment operation[2]");
27758 
27759  return error_node();
27760  }
27761  }
27762 
27764  expression_node_ptr (&branch)[2])
27765  {
27766  const bool is_b0_ivec = details::is_ivector_node(branch[0]);
27767  const bool is_b1_ivec = details::is_ivector_node(branch[1]);
27768 
27769  #define batch_eqineq_logic_case \
27770  case_stmt(details:: e_lt, details:: lt_op) \
27771  case_stmt(details:: e_lte, details:: lte_op) \
27772  case_stmt(details:: e_gt, details:: gt_op) \
27773  case_stmt(details:: e_gte, details:: gte_op) \
27774  case_stmt(details:: e_eq, details:: eq_op) \
27775  case_stmt(details:: e_ne, details:: ne_op) \
27776  case_stmt(details::e_equal, details::equal_op) \
27777  case_stmt(details:: e_and, details:: and_op) \
27778  case_stmt(details:: e_nand, details:: nand_op) \
27779  case_stmt(details:: e_or, details:: or_op) \
27780  case_stmt(details:: e_nor, details:: nor_op) \
27781  case_stmt(details:: e_xor, details:: xor_op) \
27782  case_stmt(details:: e_xnor, details:: xnor_op) \
27783 
27784  if (is_b0_ivec && is_b1_ivec)
27785  {
27786  switch (operation)
27787  {
27788  #define case_stmt(op0,op1) \
27789  case op0 : return node_allocator_-> \
27790  template allocate_rrr<typename details::vec_binop_vecvec_node<Type,op1<Type> > > \
27791  (operation, branch[0], branch[1]); \
27792 
27794  #undef case_stmt
27795  default : return error_node();
27796  }
27797  }
27798  else if (is_b0_ivec && !is_b1_ivec)
27799  {
27800  switch (operation)
27801  {
27802  #define case_stmt(op0,op1) \
27803  case op0 : return node_allocator_-> \
27804  template allocate_rrr<typename details::vec_binop_vecval_node<Type,op1<Type> > > \
27805  (operation, branch[0], branch[1]); \
27806 
27808  #undef case_stmt
27809  default : return error_node();
27810  }
27811  }
27812  else if (!is_b0_ivec && is_b1_ivec)
27813  {
27814  switch (operation)
27815  {
27816  #define case_stmt(op0,op1) \
27817  case op0 : return node_allocator_-> \
27818  template allocate_rrr<typename details::vec_binop_valvec_node<Type,op1<Type> > > \
27819  (operation, branch[0], branch[1]); \
27820 
27822  #undef case_stmt
27823  default : return error_node();
27824  }
27825  }
27826  else
27827  return error_node();
27828 
27829  #undef batch_eqineq_logic_case
27830  }
27831 
27833  expression_node_ptr (&branch)[2])
27834  {
27835  const bool is_b0_ivec = details::is_ivector_node(branch[0]);
27836  const bool is_b1_ivec = details::is_ivector_node(branch[1]);
27837 
27838  #define vector_ops \
27839  case_stmt(details::e_add,details::add_op) \
27840  case_stmt(details::e_sub,details::sub_op) \
27841  case_stmt(details::e_mul,details::mul_op) \
27842  case_stmt(details::e_div,details::div_op) \
27843  case_stmt(details::e_mod,details::mod_op) \
27844 
27845  if (is_b0_ivec && is_b1_ivec)
27846  {
27847  switch (operation)
27848  {
27849  #define case_stmt(op0,op1) \
27850  case op0 : return node_allocator_-> \
27851  template allocate_rrr<typename details::vec_binop_vecvec_node<Type,op1<Type> > > \
27852  (operation, branch[0], branch[1]); \
27853 
27854  vector_ops
27856  #undef case_stmt
27857  default : return error_node();
27858  }
27859  }
27860  else if (is_b0_ivec && !is_b1_ivec)
27861  {
27862  switch (operation)
27863  {
27864  #define case_stmt(op0,op1) \
27865  case op0 : return node_allocator_-> \
27866  template allocate_rrr<typename details::vec_binop_vecval_node<Type,op1<Type> > > \
27867  (operation, branch[0], branch[1]); \
27868 
27869  vector_ops
27871  #undef case_stmt
27872  default : return error_node();
27873  }
27874  }
27875  else if (!is_b0_ivec && is_b1_ivec)
27876  {
27877  switch (operation)
27878  {
27879  #define case_stmt(op0,op1) \
27880  case op0 : return node_allocator_-> \
27881  template allocate_rrr<typename details::vec_binop_valvec_node<Type,op1<Type> > > \
27882  (operation, branch[0], branch[1]); \
27883 
27884  vector_ops
27885  #undef case_stmt
27886  default : return error_node();
27887  }
27888  }
27889  else
27890  return error_node();
27891 
27892  #undef vector_ops
27893  }
27894 
27896  {
27897  const bool v0_is_ivar = details::is_ivariable_node(branch[0]);
27898  const bool v1_is_ivar = details::is_ivariable_node(branch[1]);
27899 
27900  const bool v0_is_ivec = details::is_ivector_node (branch[0]);
27901  const bool v1_is_ivec = details::is_ivector_node (branch[1]);
27902 
27903  #ifndef exprtk_disable_string_capabilities
27904  const bool v0_is_str = details::is_generally_string_node(branch[0]);
27905  const bool v1_is_str = details::is_generally_string_node(branch[1]);
27906  #endif
27907 
27908  expression_node_ptr result = error_node();
27909 
27910  if (v0_is_ivar && v1_is_ivar)
27911  {
27912  typedef details::variable_node<T>* variable_node_ptr;
27913 
27914  variable_node_ptr v0 = variable_node_ptr(0);
27915  variable_node_ptr v1 = variable_node_ptr(0);
27916 
27917  if (
27918  (0 != (v0 = dynamic_cast<variable_node_ptr>(branch[0]))) &&
27919  (0 != (v1 = dynamic_cast<variable_node_ptr>(branch[1])))
27920  )
27921  {
27922  result = node_allocator_->allocate<details::swap_node<T> >(v0,v1);
27923  }
27924  else
27925  result = node_allocator_->allocate<details::swap_generic_node<T> >(branch[0],branch[1]);
27926  }
27927  else if (v0_is_ivec && v1_is_ivec)
27928  {
27929  result = node_allocator_->allocate<details::swap_vecvec_node<T> >(branch[0],branch[1]);
27930  }
27931  #ifndef exprtk_disable_string_capabilities
27932  else if (v0_is_str && v1_is_str)
27933  {
27934  if (is_string_node(branch[0]) && is_string_node(branch[1]))
27935  result = node_allocator_->allocate<details::swap_string_node<T> >
27936  (branch[0], branch[1]);
27937  else
27938  result = node_allocator_->allocate<details::swap_genstrings_node<T> >
27939  (branch[0], branch[1]);
27940  }
27941  #endif
27942  else
27943  {
27944  parser_->set_synthesis_error("Only variables, strings, vectors or vector elements can be swapped");
27945 
27946  return error_node();
27947  }
27948 
27949  parser_->state_.activate_side_effect("synthesize_swap_expression()");
27950 
27951  return result;
27952  }
27953 
27954  #ifndef exprtk_disable_sc_andor
27956  {
27957  expression_node_ptr result = error_node();
27958 
27959  if (details::is_constant_node(branch[0]))
27960  {
27961  if (
27962  (details::e_scand == operation) &&
27963  std::equal_to<T>()(T(0),branch[0]->value())
27964  )
27965  result = node_allocator_->allocate_c<literal_node_t>(T(0));
27966  else if (
27967  (details::e_scor == operation) &&
27968  std::not_equal_to<T>()(T(0),branch[0]->value())
27969  )
27970  result = node_allocator_->allocate_c<literal_node_t>(T(1));
27971  }
27972 
27973  if (details::is_constant_node(branch[1]) && (0 == result))
27974  {
27975  if (
27976  (details::e_scand == operation) &&
27977  std::equal_to<T>()(T(0),branch[1]->value())
27978  )
27979  result = node_allocator_->allocate_c<literal_node_t>(T(0));
27980  else if (
27981  (details::e_scor == operation) &&
27982  std::not_equal_to<T>()(T(0),branch[1]->value())
27983  )
27984  result = node_allocator_->allocate_c<literal_node_t>(T(1));
27985  }
27986 
27987  if (result)
27988  {
27989  free_node(*node_allocator_, branch[0]);
27990  free_node(*node_allocator_, branch[1]);
27991 
27992  return result;
27993  }
27994  else if (details::e_scand == operation)
27995  {
27996  return synthesize_expression<scand_node_t,2>(operation, branch);
27997  }
27998  else if (details::e_scor == operation)
27999  {
28000  return synthesize_expression<scor_node_t,2>(operation, branch);
28001  }
28002  else
28003  return error_node();
28004  }
28005  #else
28006  inline expression_node_ptr synthesize_shortcircuit_expression(const details::operator_type&, expression_node_ptr (&)[2])
28007  {
28008  return error_node();
28009  }
28010  #endif
28011 
28012  #define basic_opr_switch_statements \
28013  case_stmt(details::e_add, details::add_op) \
28014  case_stmt(details::e_sub, details::sub_op) \
28015  case_stmt(details::e_mul, details::mul_op) \
28016  case_stmt(details::e_div, details::div_op) \
28017  case_stmt(details::e_mod, details::mod_op) \
28018  case_stmt(details::e_pow, details::pow_op) \
28019 
28020  #define extended_opr_switch_statements \
28021  case_stmt(details:: e_lt, details:: lt_op) \
28022  case_stmt(details:: e_lte, details:: lte_op) \
28023  case_stmt(details:: e_gt, details:: gt_op) \
28024  case_stmt(details:: e_gte, details:: gte_op) \
28025  case_stmt(details:: e_eq, details:: eq_op) \
28026  case_stmt(details:: e_ne, details:: ne_op) \
28027  case_stmt(details:: e_and, details:: and_op) \
28028  case_stmt(details::e_nand, details::nand_op) \
28029  case_stmt(details:: e_or, details:: or_op) \
28030  case_stmt(details:: e_nor, details:: nor_op) \
28031  case_stmt(details:: e_xor, details:: xor_op) \
28032  case_stmt(details::e_xnor, details::xnor_op) \
28033 
28034  #ifndef exprtk_disable_cardinal_pow_optimisation
28035  template <typename TType, template <typename,typename> class IPowNode>
28036  inline expression_node_ptr cardinal_pow_optimisation_impl(const TType& v, const unsigned int& p)
28037  {
28038  switch (p)
28039  {
28040  #define case_stmt(cp) \
28041  case cp : return node_allocator_-> \
28042  allocate<IPowNode<T,details::numeric::fast_exp<T,cp> > >(v); \
28043 
28044  case_stmt( 1) case_stmt( 2) case_stmt( 3) case_stmt( 4)
28045  case_stmt( 5) case_stmt( 6) case_stmt( 7) case_stmt( 8)
28046  case_stmt( 9) case_stmt(10) case_stmt(11) case_stmt(12)
28047  case_stmt(13) case_stmt(14) case_stmt(15) case_stmt(16)
28048  case_stmt(17) case_stmt(18) case_stmt(19) case_stmt(20)
28049  case_stmt(21) case_stmt(22) case_stmt(23) case_stmt(24)
28050  case_stmt(25) case_stmt(26) case_stmt(27) case_stmt(28)
28051  case_stmt(29) case_stmt(30) case_stmt(31) case_stmt(32)
28052  case_stmt(33) case_stmt(34) case_stmt(35) case_stmt(36)
28053  case_stmt(37) case_stmt(38) case_stmt(39) case_stmt(40)
28054  case_stmt(41) case_stmt(42) case_stmt(43) case_stmt(44)
28055  case_stmt(45) case_stmt(46) case_stmt(47) case_stmt(48)
28056  case_stmt(49) case_stmt(50) case_stmt(51) case_stmt(52)
28057  case_stmt(53) case_stmt(54) case_stmt(55) case_stmt(56)
28058  case_stmt(57) case_stmt(58) case_stmt(59) case_stmt(60)
28059  #undef case_stmt
28060  default : return error_node();
28061  }
28062  }
28063 
28064  inline expression_node_ptr cardinal_pow_optimisation(const T& v, const T& c)
28065  {
28066  const bool not_recipricol = (c >= T(0));
28067  const unsigned int p = static_cast<unsigned int>(details::numeric::to_int32(details::numeric::abs(c)));
28068 
28069  if (0 == p)
28070  return node_allocator_->allocate_c<literal_node_t>(T(1));
28071  else if (std::equal_to<T>()(T(2),c))
28072  {
28073  return node_allocator_->
28074  template allocate_rr<typename details::vov_node<Type,details::mul_op<Type> > >(v,v);
28075  }
28076  else
28077  {
28078  if (not_recipricol)
28079  return cardinal_pow_optimisation_impl<T,details::ipow_node>(v,p);
28080  else
28081  return cardinal_pow_optimisation_impl<T,details::ipowinv_node>(v,p);
28082  }
28083  }
28084 
28085  inline bool cardinal_pow_optimisable(const details::operator_type& operation, const T& c)
28086  {
28087  return (details::e_pow == operation) && (details::numeric::abs(c) <= T(60)) && details::numeric::is_integer(c);
28088  }
28089 
28091  {
28092  const Type c = static_cast<details::literal_node<Type>*>(branch[1])->value();
28093  const bool not_recipricol = (c >= T(0));
28094  const unsigned int p = static_cast<unsigned int>(details::numeric::to_int32(details::numeric::abs(c)));
28095 
28096  node_allocator_->free(branch[1]);
28097 
28098  if (0 == p)
28099  {
28100  details::free_all_nodes(*node_allocator_, branch);
28101 
28102  return node_allocator_->allocate_c<literal_node_t>(T(1));
28103  }
28104  else if (not_recipricol)
28105  return cardinal_pow_optimisation_impl<expression_node_ptr,details::bipow_node>(branch[0],p);
28106  else
28107  return cardinal_pow_optimisation_impl<expression_node_ptr,details::bipowninv_node>(branch[0],p);
28108  }
28109  #else
28110  inline expression_node_ptr cardinal_pow_optimisation(T&, const T&)
28111  {
28112  return error_node();
28113  }
28114 
28115  inline bool cardinal_pow_optimisable(const details::operator_type&, const T&)
28116  {
28117  return false;
28118  }
28119 
28120  inline expression_node_ptr cardinal_pow_optimisation(expression_node_ptr(&)[2])
28121  {
28122  return error_node();
28123  }
28124  #endif
28125 
28127  {
28129  const details::operator_type& operation,
28130  expression_node_ptr (&branch)[2])
28131  {
28132  const bool left_neg = is_neg_unary_node(branch[0]);
28133  const bool right_neg = is_neg_unary_node(branch[1]);
28134 
28135  if (left_neg && right_neg)
28136  {
28137  if (
28138  (details::e_add == operation) ||
28139  (details::e_sub == operation) ||
28140  (details::e_mul == operation) ||
28141  (details::e_div == operation)
28142  )
28143  {
28144  if (
28145  !expr_gen.parser_->simplify_unary_negation_branch(branch[0]) ||
28146  !expr_gen.parser_->simplify_unary_negation_branch(branch[1])
28147  )
28148  {
28149  details::free_all_nodes(*expr_gen.node_allocator_,branch);
28150 
28151  return error_node();
28152  }
28153  }
28154 
28155  switch (operation)
28156  {
28157  // -f(x + 1) + -g(y + 1) --> -(f(x + 1) + g(y + 1))
28158  case details::e_add : return expr_gen(details::e_neg,
28159  expr_gen.node_allocator_->
28160  template allocate<typename details::binary_ext_node<Type,details::add_op<Type> > >
28161  (branch[0],branch[1]));
28162 
28163  // -f(x + 1) - -g(y + 1) --> g(y + 1) - f(x + 1)
28164  case details::e_sub : return expr_gen.node_allocator_->
28165  template allocate<typename details::binary_ext_node<Type,details::sub_op<Type> > >
28166  (branch[1],branch[0]);
28167 
28168  default : break;
28169  }
28170  }
28171  else if (left_neg && !right_neg)
28172  {
28173  if (
28174  (details::e_add == operation) ||
28175  (details::e_sub == operation) ||
28176  (details::e_mul == operation) ||
28177  (details::e_div == operation)
28178  )
28179  {
28180  if (!expr_gen.parser_->simplify_unary_negation_branch(branch[0]))
28181  {
28182  details::free_all_nodes(*expr_gen.node_allocator_,branch);
28183 
28184  return error_node();
28185  }
28186 
28187  switch (operation)
28188  {
28189  // -f(x + 1) + g(y + 1) --> g(y + 1) - f(x + 1)
28190  case details::e_add : return expr_gen.node_allocator_->
28191  template allocate<typename details::binary_ext_node<Type,details::sub_op<Type> > >
28192  (branch[1], branch[0]);
28193 
28194  // -f(x + 1) - g(y + 1) --> -(f(x + 1) + g(y + 1))
28195  case details::e_sub : return expr_gen(details::e_neg,
28196  expr_gen.node_allocator_->
28197  template allocate<typename details::binary_ext_node<Type,details::add_op<Type> > >
28198  (branch[0], branch[1]));
28199 
28200  // -f(x + 1) * g(y + 1) --> -(f(x + 1) * g(y + 1))
28201  case details::e_mul : return expr_gen(details::e_neg,
28202  expr_gen.node_allocator_->
28203  template allocate<typename details::binary_ext_node<Type,details::mul_op<Type> > >
28204  (branch[0], branch[1]));
28205 
28206  // -f(x + 1) / g(y + 1) --> -(f(x + 1) / g(y + 1))
28207  case details::e_div : return expr_gen(details::e_neg,
28208  expr_gen.node_allocator_->
28209  template allocate<typename details::binary_ext_node<Type,details::div_op<Type> > >
28210  (branch[0], branch[1]));
28211 
28212  default : return error_node();
28213  }
28214  }
28215  }
28216  else if (!left_neg && right_neg)
28217  {
28218  if (
28219  (details::e_add == operation) ||
28220  (details::e_sub == operation) ||
28221  (details::e_mul == operation) ||
28222  (details::e_div == operation)
28223  )
28224  {
28225  if (!expr_gen.parser_->simplify_unary_negation_branch(branch[1]))
28226  {
28227  details::free_all_nodes(*expr_gen.node_allocator_,branch);
28228 
28229  return error_node();
28230  }
28231 
28232  switch (operation)
28233  {
28234  // f(x + 1) + -g(y + 1) --> f(x + 1) - g(y + 1)
28235  case details::e_add : return expr_gen.node_allocator_->
28236  template allocate<typename details::binary_ext_node<Type,details::sub_op<Type> > >
28237  (branch[0], branch[1]);
28238 
28239  // f(x + 1) - - g(y + 1) --> f(x + 1) + g(y + 1)
28240  case details::e_sub : return expr_gen.node_allocator_->
28241  template allocate<typename details::binary_ext_node<Type,details::add_op<Type> > >
28242  (branch[0], branch[1]);
28243 
28244  // f(x + 1) * -g(y + 1) --> -(f(x + 1) * g(y + 1))
28245  case details::e_mul : return expr_gen(details::e_neg,
28246  expr_gen.node_allocator_->
28247  template allocate<typename details::binary_ext_node<Type,details::mul_op<Type> > >
28248  (branch[0], branch[1]));
28249 
28250  // f(x + 1) / -g(y + 1) --> -(f(x + 1) / g(y + 1))
28251  case details::e_div : return expr_gen(details::e_neg,
28252  expr_gen.node_allocator_->
28253  template allocate<typename details::binary_ext_node<Type,details::div_op<Type> > >
28254  (branch[0], branch[1]));
28255 
28256  default : return error_node();
28257  }
28258  }
28259  }
28260 
28261  switch (operation)
28262  {
28263  #define case_stmt(op0,op1) \
28264  case op0 : return expr_gen.node_allocator_-> \
28265  template allocate<typename details::binary_ext_node<Type,op1<Type> > > \
28266  (branch[0], branch[1]); \
28267 
28270  #undef case_stmt
28271  default : return error_node();
28272  }
28273  }
28274  };
28275 
28277  {
28279  const details::operator_type& operation,
28280  expression_node_ptr (&branch)[2])
28281  {
28282  const Type& v = static_cast<details::variable_node<Type>*>(branch[0])->ref();
28283 
28284  #ifndef exprtk_disable_enhanced_features
28285  if (details::is_sf3ext_node(branch[1]))
28286  {
28287  expression_node_ptr result = error_node();
28288 
28289  const bool synthesis_result = synthesize_sf4ext_expression::template compile_right<vtype>
28290  (expr_gen, v, operation, branch[1], result);
28291 
28292  if (synthesis_result)
28293  {
28294  free_node(*expr_gen.node_allocator_,branch[1]);
28295  return result;
28296  }
28297  }
28298  #endif
28299 
28300  if (
28301  (details::e_mul == operation) ||
28302  (details::e_div == operation)
28303  )
28304  {
28305  if (details::is_uv_node(branch[1]))
28306  {
28307  typedef details::uv_base_node<Type>* uvbn_ptr_t;
28308 
28309  details::operator_type o = static_cast<uvbn_ptr_t>(branch[1])->operation();
28310 
28311  if (details::e_neg == o)
28312  {
28313  const Type& v1 = static_cast<uvbn_ptr_t>(branch[1])->v();
28314 
28315  free_node(*expr_gen.node_allocator_,branch[1]);
28316 
28317  switch (operation)
28318  {
28319  case details::e_mul : return expr_gen(details::e_neg,
28320  expr_gen.node_allocator_->
28321  template allocate_rr<typename details::
28322  vov_node<Type,details::mul_op<Type> > >(v,v1));
28323 
28324  case details::e_div : return expr_gen(details::e_neg,
28325  expr_gen.node_allocator_->
28326  template allocate_rr<typename details::
28327  vov_node<Type,details::div_op<Type> > >(v,v1));
28328 
28329  default : break;
28330  }
28331  }
28332  }
28333  }
28334 
28335  switch (operation)
28336  {
28337  #define case_stmt(op0,op1) \
28338  case op0 : return expr_gen.node_allocator_-> \
28339  template allocate_rc<typename details::vob_node<Type,op1<Type> > > \
28340  (v, branch[1]); \
28341 
28344  #undef case_stmt
28345  default : return error_node();
28346  }
28347  }
28348  };
28349 
28351  {
28353  const details::operator_type& operation,
28354  expression_node_ptr (&branch)[2])
28355  {
28356  const Type& v = static_cast<details::variable_node<Type>*>(branch[1])->ref();
28357 
28358  #ifndef exprtk_disable_enhanced_features
28359  if (details::is_sf3ext_node(branch[0]))
28360  {
28361  expression_node_ptr result = error_node();
28362 
28363  const bool synthesis_result = synthesize_sf4ext_expression::template compile_left<vtype>
28364  (expr_gen, v, operation, branch[0], result);
28365 
28366  if (synthesis_result)
28367  {
28368  free_node(*expr_gen.node_allocator_, branch[0]);
28369 
28370  return result;
28371  }
28372  }
28373  #endif
28374 
28375  if (
28376  (details::e_add == operation) ||
28377  (details::e_sub == operation) ||
28378  (details::e_mul == operation) ||
28379  (details::e_div == operation)
28380  )
28381  {
28382  if (details::is_uv_node(branch[0]))
28383  {
28384  typedef details::uv_base_node<Type>* uvbn_ptr_t;
28385 
28386  details::operator_type o = static_cast<uvbn_ptr_t>(branch[0])->operation();
28387 
28388  if (details::e_neg == o)
28389  {
28390  const Type& v0 = static_cast<uvbn_ptr_t>(branch[0])->v();
28391 
28392  free_node(*expr_gen.node_allocator_,branch[0]);
28393 
28394  switch (operation)
28395  {
28396  case details::e_add : return expr_gen.node_allocator_->
28397  template allocate_rr<typename details::
28399 
28400  case details::e_sub : return expr_gen(details::e_neg,
28401  expr_gen.node_allocator_->
28402  template allocate_rr<typename details::
28403  vov_node<Type,details::add_op<Type> > >(v0,v));
28404 
28405  case details::e_mul : return expr_gen(details::e_neg,
28406  expr_gen.node_allocator_->
28407  template allocate_rr<typename details::
28408  vov_node<Type,details::mul_op<Type> > >(v0,v));
28409 
28410  case details::e_div : return expr_gen(details::e_neg,
28411  expr_gen.node_allocator_->
28412  template allocate_rr<typename details::
28413  vov_node<Type,details::div_op<Type> > >(v0,v));
28414  default : break;
28415  }
28416  }
28417  }
28418  }
28419 
28420  switch (operation)
28421  {
28422  #define case_stmt(op0,op1) \
28423  case op0 : return expr_gen.node_allocator_-> \
28424  template allocate_cr<typename details::bov_node<Type,op1<Type> > > \
28425  (branch[0], v); \
28426 
28429  #undef case_stmt
28430  default : return error_node();
28431  }
28432  }
28433  };
28434 
28436  {
28438  const details::operator_type& operation,
28439  expression_node_ptr (&branch)[2])
28440  {
28441  const Type c = static_cast<details::literal_node<Type>*>(branch[0])->value();
28442 
28443  free_node(*expr_gen.node_allocator_,branch[0]);
28444 
28445  if (std::equal_to<T>()(T(0),c) && (details::e_mul == operation))
28446  {
28447  free_node(*expr_gen.node_allocator_,branch[1]);
28448 
28449  return expr_gen(T(0));
28450  }
28451  else if (std::equal_to<T>()(T(0),c) && (details::e_div == operation))
28452  {
28453  free_node(*expr_gen.node_allocator_, branch[1]);
28454 
28455  return expr_gen(T(0));
28456  }
28457  else if (std::equal_to<T>()(T(0),c) && (details::e_add == operation))
28458  return branch[1];
28459  else if (std::equal_to<T>()(T(1),c) && (details::e_mul == operation))
28460  return branch[1];
28461 
28462  if (details::is_cob_node(branch[1]))
28463  {
28464  // Simplify expressions of the form:
28465  // 1. (1 * (2 * (3 * (4 * (5 * (6 * (7 * (8 * (9 + x))))))))) --> 40320 * (9 + x)
28466  // 2. (1 + (2 + (3 + (4 + (5 + (6 + (7 + (8 + (9 + x))))))))) --> 45 + x
28467  if (
28468  (operation == details::e_mul) ||
28469  (operation == details::e_add)
28470  )
28471  {
28472  details::cob_base_node<Type>* cobnode = static_cast<details::cob_base_node<Type>*>(branch[1]);
28473 
28474  if (operation == cobnode->operation())
28475  {
28476  switch (operation)
28477  {
28478  case details::e_add : cobnode->set_c(c + cobnode->c()); break;
28479  case details::e_mul : cobnode->set_c(c * cobnode->c()); break;
28480  default : return error_node();
28481  }
28482 
28483  return cobnode;
28484  }
28485  }
28486 
28487  if (operation == details::e_mul)
28488  {
28489  details::cob_base_node<Type>* cobnode = static_cast<details::cob_base_node<Type>*>(branch[1]);
28490  details::operator_type cob_opr = cobnode->operation();
28491 
28492  if (
28493  (details::e_div == cob_opr) ||
28494  (details::e_mul == cob_opr)
28495  )
28496  {
28497  switch (cob_opr)
28498  {
28499  case details::e_div : cobnode->set_c(c * cobnode->c()); break;
28500  case details::e_mul : cobnode->set_c(cobnode->c() / c); break;
28501  default : return error_node();
28502  }
28503 
28504  return cobnode;
28505  }
28506  }
28507  else if (operation == details::e_div)
28508  {
28509  details::cob_base_node<Type>* cobnode = static_cast<details::cob_base_node<Type>*>(branch[1]);
28510  details::operator_type cob_opr = cobnode->operation();
28511 
28512  if (
28513  (details::e_div == cob_opr) ||
28514  (details::e_mul == cob_opr)
28515  )
28516  {
28517  details::expression_node<Type>* new_cobnode = error_node();
28518 
28519  switch (cob_opr)
28520  {
28521  case details::e_div : new_cobnode = expr_gen.node_allocator_->
28522  template allocate_tt<typename details::cob_node<Type,details::mul_op<Type> > >
28523  (c / cobnode->c(), cobnode->move_branch(0));
28524  break;
28525 
28526  case details::e_mul : new_cobnode = expr_gen.node_allocator_->
28527  template allocate_tt<typename details::cob_node<Type,details::div_op<Type> > >
28528  (c / cobnode->c(), cobnode->move_branch(0));
28529  break;
28530 
28531  default : return error_node();
28532  }
28533 
28534  free_node(*expr_gen.node_allocator_,branch[1]);
28535 
28536  return new_cobnode;
28537  }
28538  }
28539  }
28540  #ifndef exprtk_disable_enhanced_features
28541  else if (details::is_sf3ext_node(branch[1]))
28542  {
28543  expression_node_ptr result = error_node();
28544 
28545  if (synthesize_sf4ext_expression::template compile_right<ctype>(expr_gen,c,operation,branch[1],result))
28546  {
28547  free_node(*expr_gen.node_allocator_,branch[1]);
28548 
28549  return result;
28550  }
28551  }
28552  #endif
28553 
28554  switch (operation)
28555  {
28556  #define case_stmt(op0,op1) \
28557  case op0 : return expr_gen.node_allocator_-> \
28558  template allocate_tt<typename details::cob_node<Type,op1<Type> > > \
28559  (c, branch[1]); \
28560 
28563  #undef case_stmt
28564  default : return error_node();
28565  }
28566  }
28567  };
28568 
28570  {
28572  const details::operator_type& operation,
28573  expression_node_ptr (&branch)[2])
28574  {
28575  const Type c = static_cast<details::literal_node<Type>*>(branch[1])->value();
28576 
28577  details::free_node(*(expr_gen.node_allocator_), branch[1]);
28578 
28579  if (std::equal_to<T>()(T(0),c) && (details::e_mul == operation))
28580  {
28581  free_node(*expr_gen.node_allocator_, branch[0]);
28582 
28583  return expr_gen(T(0));
28584  }
28585  else if (std::equal_to<T>()(T(0),c) && (details::e_div == operation))
28586  {
28587  free_node(*expr_gen.node_allocator_, branch[0]);
28588 
28589  return expr_gen(std::numeric_limits<T>::quiet_NaN());
28590  }
28591  else if (std::equal_to<T>()(T(0),c) && (details::e_add == operation))
28592  return branch[0];
28593  else if (std::equal_to<T>()(T(1),c) && (details::e_mul == operation))
28594  return branch[0];
28595 
28596  if (details::is_boc_node(branch[0]))
28597  {
28598  // Simplify expressions of the form:
28599  // 1. (((((((((x + 9) * 8) * 7) * 6) * 5) * 4) * 3) * 2) * 1) --> (x + 9) * 40320
28600  // 2. (((((((((x + 9) + 8) + 7) + 6) + 5) + 4) + 3) + 2) + 1) --> x + 45
28601  if (
28602  (operation == details::e_mul) ||
28603  (operation == details::e_add)
28604  )
28605  {
28606  details::boc_base_node<Type>* bocnode = static_cast<details::boc_base_node<Type>*>(branch[0]);
28607 
28608  if (operation == bocnode->operation())
28609  {
28610  switch (operation)
28611  {
28612  case details::e_add : bocnode->set_c(c + bocnode->c()); break;
28613  case details::e_mul : bocnode->set_c(c * bocnode->c()); break;
28614  default : return error_node();
28615  }
28616 
28617  return bocnode;
28618  }
28619  }
28620  else if (operation == details::e_div)
28621  {
28622  details::boc_base_node<Type>* bocnode = static_cast<details::boc_base_node<Type>*>(branch[0]);
28623  details::operator_type boc_opr = bocnode->operation();
28624 
28625  if (
28626  (details::e_div == boc_opr) ||
28627  (details::e_mul == boc_opr)
28628  )
28629  {
28630  switch (boc_opr)
28631  {
28632  case details::e_div : bocnode->set_c(c * bocnode->c()); break;
28633  case details::e_mul : bocnode->set_c(bocnode->c() / c); break;
28634  default : return error_node();
28635  }
28636 
28637  return bocnode;
28638  }
28639  }
28640  else if (operation == details::e_pow)
28641  {
28642  // (v ^ c0) ^ c1 --> v ^(c0 * c1)
28643  details::boc_base_node<Type>* bocnode = static_cast<details::boc_base_node<Type>*>(branch[0]);
28644  details::operator_type boc_opr = bocnode->operation();
28645 
28646  if (details::e_pow == boc_opr)
28647  {
28648  bocnode->set_c(bocnode->c() * c);
28649 
28650  return bocnode;
28651  }
28652  }
28653  }
28654 
28655  #ifndef exprtk_disable_enhanced_features
28656  if (details::is_sf3ext_node(branch[0]))
28657  {
28658  expression_node_ptr result = error_node();
28659 
28660  const bool synthesis_result = synthesize_sf4ext_expression::template compile_left<ctype>
28661  (expr_gen, c, operation, branch[0], result);
28662 
28663  if (synthesis_result)
28664  {
28665  free_node(*expr_gen.node_allocator_, branch[0]);
28666 
28667  return result;
28668  }
28669  }
28670  #endif
28671 
28672  switch (operation)
28673  {
28674  #define case_stmt(op0,op1) \
28675  case op0 : return expr_gen.node_allocator_-> \
28676  template allocate_cr<typename details::boc_node<Type,op1<Type> > > \
28677  (branch[0], c); \
28678 
28681  #undef case_stmt
28682  default : return error_node();
28683  }
28684  }
28685  };
28686 
28688  {
28690  const details::operator_type& operation,
28691  expression_node_ptr (&branch)[2])
28692  {
28693  expression_node_ptr result = error_node();
28694 
28695  // (cob) o c --> cob
28696  if (details::is_cob_node(branch[0]))
28697  {
28698  details::cob_base_node<Type>* cobnode = static_cast<details::cob_base_node<Type>*>(branch[0]);
28699 
28700  const Type c = static_cast<details::literal_node<Type>*>(branch[1])->value();
28701 
28702  if (std::equal_to<T>()(T(0),c) && (details::e_mul == operation))
28703  {
28704  free_node(*expr_gen.node_allocator_, branch[0]);
28705  free_node(*expr_gen.node_allocator_, branch[1]);
28706 
28707  return expr_gen(T(0));
28708  }
28709  else if (std::equal_to<T>()(T(0),c) && (details::e_div == operation))
28710  {
28711  free_node(*expr_gen.node_allocator_, branch[0]);
28712  free_node(*expr_gen.node_allocator_, branch[1]);
28713 
28714  return expr_gen(T(std::numeric_limits<T>::quiet_NaN()));
28715  }
28716  else if (std::equal_to<T>()(T(0),c) && (details::e_add == operation))
28717  {
28718  free_node(*expr_gen.node_allocator_, branch[1]);
28719 
28720  return branch[0];
28721  }
28722  else if (std::equal_to<T>()(T(1),c) && (details::e_mul == operation))
28723  {
28724  free_node(*expr_gen.node_allocator_, branch[1]);
28725 
28726  return branch[0];
28727  }
28728  else if (std::equal_to<T>()(T(1),c) && (details::e_div == operation))
28729  {
28730  free_node(*expr_gen.node_allocator_, branch[1]);
28731 
28732  return branch[0];
28733  }
28734 
28735  const bool op_addsub = (details::e_add == cobnode->operation()) ||
28736  (details::e_sub == cobnode->operation()) ;
28737 
28738  if (op_addsub)
28739  {
28740  switch (operation)
28741  {
28742  case details::e_add : cobnode->set_c(cobnode->c() + c); break;
28743  case details::e_sub : cobnode->set_c(cobnode->c() - c); break;
28744  default : return error_node();
28745  }
28746 
28747  result = cobnode;
28748  }
28749  else if (details::e_mul == cobnode->operation())
28750  {
28751  switch (operation)
28752  {
28753  case details::e_mul : cobnode->set_c(cobnode->c() * c); break;
28754  case details::e_div : cobnode->set_c(cobnode->c() / c); break;
28755  default : return error_node();
28756  }
28757 
28758  result = cobnode;
28759  }
28760  else if (details::e_div == cobnode->operation())
28761  {
28762  if (details::e_mul == operation)
28763  {
28764  cobnode->set_c(cobnode->c() * c);
28765  result = cobnode;
28766  }
28767  else if (details::e_div == operation)
28768  {
28769  result = expr_gen.node_allocator_->
28770  template allocate_tt<typename details::cob_node<Type,details::div_op<Type> > >
28771  (cobnode->c() / c, cobnode->move_branch(0));
28772 
28773  free_node(*expr_gen.node_allocator_, branch[0]);
28774  }
28775  }
28776 
28777  if (result)
28778  {
28779  free_node(*expr_gen.node_allocator_,branch[1]);
28780  }
28781  }
28782 
28783  // c o (cob) --> cob
28784  else if (details::is_cob_node(branch[1]))
28785  {
28786  details::cob_base_node<Type>* cobnode = static_cast<details::cob_base_node<Type>*>(branch[1]);
28787 
28788  const Type c = static_cast<details::literal_node<Type>*>(branch[0])->value();
28789 
28790  if (std::equal_to<T>()(T(0),c) && (details::e_mul == operation))
28791  {
28792  free_node(*expr_gen.node_allocator_, branch[0]);
28793  free_node(*expr_gen.node_allocator_, branch[1]);
28794 
28795  return expr_gen(T(0));
28796  }
28797  else if (std::equal_to<T>()(T(0),c) && (details::e_div == operation))
28798  {
28799  free_node(*expr_gen.node_allocator_, branch[0]);
28800  free_node(*expr_gen.node_allocator_, branch[1]);
28801 
28802  return expr_gen(T(0));
28803  }
28804  else if (std::equal_to<T>()(T(0),c) && (details::e_add == operation))
28805  {
28806  free_node(*expr_gen.node_allocator_, branch[0]);
28807 
28808  return branch[1];
28809  }
28810  else if (std::equal_to<T>()(T(1),c) && (details::e_mul == operation))
28811  {
28812  free_node(*expr_gen.node_allocator_, branch[0]);
28813 
28814  return branch[1];
28815  }
28816 
28817  if (details::e_add == cobnode->operation())
28818  {
28819  if (details::e_add == operation)
28820  {
28821  cobnode->set_c(c + cobnode->c());
28822  result = cobnode;
28823  }
28824  else if (details::e_sub == operation)
28825  {
28826  result = expr_gen.node_allocator_->
28827  template allocate_tt<typename details::cob_node<Type,details::sub_op<Type> > >
28828  (c - cobnode->c(), cobnode->move_branch(0));
28829 
28830  free_node(*expr_gen.node_allocator_,branch[1]);
28831  }
28832  }
28833  else if (details::e_sub == cobnode->operation())
28834  {
28835  if (details::e_add == operation)
28836  {
28837  cobnode->set_c(c + cobnode->c());
28838  result = cobnode;
28839  }
28840  else if (details::e_sub == operation)
28841  {
28842  result = expr_gen.node_allocator_->
28843  template allocate_tt<typename details::cob_node<Type,details::add_op<Type> > >
28844  (c - cobnode->c(), cobnode->move_branch(0));
28845 
28846  free_node(*expr_gen.node_allocator_,branch[1]);
28847  }
28848  }
28849  else if (details::e_mul == cobnode->operation())
28850  {
28851  if (details::e_mul == operation)
28852  {
28853  cobnode->set_c(c * cobnode->c());
28854  result = cobnode;
28855  }
28856  else if (details::e_div == operation)
28857  {
28858  result = expr_gen.node_allocator_->
28859  template allocate_tt<typename details::cob_node<Type,details::div_op<Type> > >
28860  (c / cobnode->c(), cobnode->move_branch(0));
28861 
28862  free_node(*expr_gen.node_allocator_,branch[1]);
28863  }
28864  }
28865  else if (details::e_div == cobnode->operation())
28866  {
28867  if (details::e_mul == operation)
28868  {
28869  cobnode->set_c(c * cobnode->c());
28870  result = cobnode;
28871  }
28872  else if (details::e_div == operation)
28873  {
28874  result = expr_gen.node_allocator_->
28875  template allocate_tt<typename details::cob_node<Type,details::mul_op<Type> > >
28876  (c / cobnode->c(), cobnode->move_branch(0));
28877 
28878  free_node(*expr_gen.node_allocator_,branch[1]);
28879  }
28880  }
28881 
28882  if (result)
28883  {
28884  free_node(*expr_gen.node_allocator_,branch[0]);
28885  }
28886  }
28887 
28888  return result;
28889  }
28890  };
28891 
28893  {
28895  const details::operator_type& operation,
28896  expression_node_ptr (&branch)[2])
28897  {
28898  expression_node_ptr result = error_node();
28899 
28900  // (boc) o c --> boc
28901  if (details::is_boc_node(branch[0]))
28902  {
28903  details::boc_base_node<Type>* bocnode = static_cast<details::boc_base_node<Type>*>(branch[0]);
28904 
28905  const Type c = static_cast<details::literal_node<Type>*>(branch[1])->value();
28906 
28907  if (details::e_add == bocnode->operation())
28908  {
28909  switch (operation)
28910  {
28911  case details::e_add : bocnode->set_c(bocnode->c() + c); break;
28912  case details::e_sub : bocnode->set_c(bocnode->c() - c); break;
28913  default : return error_node();
28914  }
28915 
28916  result = bocnode;
28917  }
28918  else if (details::e_mul == bocnode->operation())
28919  {
28920  switch (operation)
28921  {
28922  case details::e_mul : bocnode->set_c(bocnode->c() * c); break;
28923  case details::e_div : bocnode->set_c(bocnode->c() / c); break;
28924  default : return error_node();
28925  }
28926 
28927  result = bocnode;
28928  }
28929  else if (details::e_sub == bocnode->operation())
28930  {
28931  if (details::e_add == operation)
28932  {
28933  result = expr_gen.node_allocator_->
28934  template allocate_tt<typename details::boc_node<Type,details::add_op<Type> > >
28935  (bocnode->move_branch(0), c - bocnode->c());
28936 
28937  free_node(*expr_gen.node_allocator_,branch[0]);
28938  }
28939  else if (details::e_sub == operation)
28940  {
28941  bocnode->set_c(bocnode->c() + c);
28942  result = bocnode;
28943  }
28944  }
28945  else if (details::e_div == bocnode->operation())
28946  {
28947  switch (operation)
28948  {
28949  case details::e_div : bocnode->set_c(bocnode->c() * c); break;
28950  case details::e_mul : bocnode->set_c(bocnode->c() / c); break;
28951  default : return error_node();
28952  }
28953 
28954  result = bocnode;
28955  }
28956 
28957  if (result)
28958  {
28959  free_node(*expr_gen.node_allocator_, branch[1]);
28960  }
28961  }
28962 
28963  // c o (boc) --> boc
28964  else if (details::is_boc_node(branch[1]))
28965  {
28966  details::boc_base_node<Type>* bocnode = static_cast<details::boc_base_node<Type>*>(branch[1]);
28967 
28968  const Type c = static_cast<details::literal_node<Type>*>(branch[0])->value();
28969 
28970  if (details::e_add == bocnode->operation())
28971  {
28972  if (details::e_add == operation)
28973  {
28974  bocnode->set_c(c + bocnode->c());
28975  result = bocnode;
28976  }
28977  else if (details::e_sub == operation)
28978  {
28979  result = expr_gen.node_allocator_->
28980  template allocate_tt<typename details::cob_node<Type,details::sub_op<Type> > >
28981  (c - bocnode->c(), bocnode->move_branch(0));
28982 
28983  free_node(*expr_gen.node_allocator_,branch[1]);
28984  }
28985  }
28986  else if (details::e_sub == bocnode->operation())
28987  {
28988  if (details::e_add == operation)
28989  {
28990  result = expr_gen.node_allocator_->
28991  template allocate_tt<typename details::boc_node<Type,details::add_op<Type> > >
28992  (bocnode->move_branch(0), c - bocnode->c());
28993 
28994  free_node(*expr_gen.node_allocator_,branch[1]);
28995  }
28996  else if (details::e_sub == operation)
28997  {
28998  result = expr_gen.node_allocator_->
28999  template allocate_tt<typename details::cob_node<Type,details::sub_op<Type> > >
29000  (c + bocnode->c(), bocnode->move_branch(0));
29001 
29002  free_node(*expr_gen.node_allocator_,branch[1]);
29003  }
29004  }
29005  else if (details::e_mul == bocnode->operation())
29006  {
29007  if (details::e_mul == operation)
29008  {
29009  bocnode->set_c(c * bocnode->c());
29010  result = bocnode;
29011  }
29012  else if (details::e_div == operation)
29013  {
29014  result = expr_gen.node_allocator_->
29015  template allocate_tt<typename details::cob_node<Type,details::div_op<Type> > >
29016  (c / bocnode->c(), bocnode->move_branch(0));
29017 
29018  free_node(*expr_gen.node_allocator_,branch[1]);
29019  }
29020  }
29021  else if (details::e_div == bocnode->operation())
29022  {
29023  if (details::e_mul == operation)
29024  {
29025  bocnode->set_c(bocnode->c() / c);
29026  result = bocnode;
29027  }
29028  else if (details::e_div == operation)
29029  {
29030  result = expr_gen.node_allocator_->
29031  template allocate_tt<typename details::cob_node<Type,details::div_op<Type> > >
29032  (c * bocnode->c(), bocnode->move_branch(0));
29033 
29034  free_node(*expr_gen.node_allocator_,branch[1]);
29035  }
29036  }
29037 
29038  if (result)
29039  {
29040  free_node(*expr_gen.node_allocator_,branch[0]);
29041  }
29042  }
29043 
29044  return result;
29045  }
29046  };
29047 
29048  #ifndef exprtk_disable_enhanced_features
29049  inline bool synthesize_expression(const details::operator_type& operation,
29050  expression_node_ptr (&branch)[2],
29051  expression_node_ptr& result)
29052  {
29053  result = error_node();
29054 
29055  if (!operation_optimisable(operation))
29056  return false;
29057 
29058  const std::string node_id = branch_to_id(branch);
29059 
29060  const typename synthesize_map_t::iterator itr = synthesize_map_.find(node_id);
29061 
29062  if (synthesize_map_.end() != itr)
29063  {
29064  result = itr->second((*this), operation, branch);
29065 
29066  return true;
29067  }
29068  else
29069  return false;
29070  }
29071 
29073  {
29075  const details::operator_type& operation,
29076  expression_node_ptr (&branch)[2])
29077  {
29078  const Type& v1 = static_cast<details::variable_node<Type>*>(branch[0])->ref();
29079  const Type& v2 = static_cast<details::variable_node<Type>*>(branch[1])->ref();
29080 
29081  switch (operation)
29082  {
29083  #define case_stmt(op0,op1) \
29084  case op0 : return expr_gen.node_allocator_-> \
29085  template allocate_rr<typename details::vov_node<Type,op1<Type> > > \
29086  (v1, v2); \
29087 
29090  #undef case_stmt
29091  default : return error_node();
29092  }
29093  }
29094  };
29095 
29097  {
29099  const details::operator_type& operation,
29100  expression_node_ptr (&branch)[2])
29101  {
29102  const Type c = static_cast<details::literal_node<Type>*> (branch[0])->value();
29103  const Type& v = static_cast<details::variable_node<Type>*>(branch[1])->ref ();
29104 
29105  details::free_node(*(expr_gen.node_allocator_),branch[0]);
29106 
29107  if (std::equal_to<T>()(T(0),c) && (details::e_mul == operation))
29108  return expr_gen(T(0));
29109  else if (std::equal_to<T>()(T(0),c) && (details::e_div == operation))
29110  return expr_gen(T(0));
29111  else if (std::equal_to<T>()(T(0),c) && (details::e_add == operation))
29112  return static_cast<details::variable_node<Type>*>(branch[1]);
29113  else if (std::equal_to<T>()(T(1),c) && (details::e_mul == operation))
29114  return static_cast<details::variable_node<Type>*>(branch[1]);
29115 
29116  switch (operation)
29117  {
29118  #define case_stmt(op0,op1) \
29119  case op0 : return expr_gen.node_allocator_-> \
29120  template allocate_cr<typename details::cov_node<Type,op1<Type> > > \
29121  (c, v); \
29122 
29125  #undef case_stmt
29126  default : return error_node();
29127  }
29128  }
29129  };
29130 
29132  {
29134  const details::operator_type& operation,
29135  expression_node_ptr (&branch)[2])
29136  {
29137  const Type& v = static_cast<details::variable_node<Type>*>(branch[0])->ref ();
29138  const Type c = static_cast<details::literal_node<Type>*> (branch[1])->value();
29139 
29140  details::free_node(*(expr_gen.node_allocator_), branch[1]);
29141 
29142  if (expr_gen.cardinal_pow_optimisable(operation,c))
29143  {
29144  if (std::equal_to<T>()(T(1),c))
29145  return branch[0];
29146  else
29147  return expr_gen.cardinal_pow_optimisation(v,c);
29148  }
29149  else if (std::equal_to<T>()(T(0),c) && (details::e_mul == operation))
29150  return expr_gen(T(0));
29151  else if (std::equal_to<T>()(T(0),c) && (details::e_div == operation))
29152  return expr_gen(std::numeric_limits<T>::quiet_NaN());
29153  else if (std::equal_to<T>()(T(0),c) && (details::e_add == operation))
29154  return static_cast<details::variable_node<Type>*>(branch[0]);
29155  else if (std::equal_to<T>()(T(1),c) && (details::e_mul == operation))
29156  return static_cast<details::variable_node<Type>*>(branch[0]);
29157  else if (std::equal_to<T>()(T(1),c) && (details::e_div == operation))
29158  return static_cast<details::variable_node<Type>*>(branch[0]);
29159 
29160  switch (operation)
29161  {
29162  #define case_stmt(op0,op1) \
29163  case op0 : return expr_gen.node_allocator_-> \
29164  template allocate_rc<typename details::voc_node<Type,op1<Type> > > \
29165  (v, c); \
29166 
29169  #undef case_stmt
29170  default : return error_node();
29171  }
29172  }
29173  };
29174 
29176  {
29177  template <typename T0, typename T1, typename T2>
29179  const details::operator_type& sf3opr,
29180  T0 t0, T1 t1, T2 t2)
29181  {
29182  switch (sf3opr)
29183  {
29184  #define case_stmt(op) \
29185  case details::e_sf##op : return details::T0oT1oT2_sf3ext<T,T0,T1,T2,details::sf##op##_op<Type> >:: \
29186  allocate(*(expr_gen.node_allocator_), t0, t1, t2); \
29187 
29188  case_stmt(00) case_stmt(01) case_stmt(02) case_stmt(03)
29189  case_stmt(04) case_stmt(05) case_stmt(06) case_stmt(07)
29190  case_stmt(08) case_stmt(09) case_stmt(10) case_stmt(11)
29191  case_stmt(12) case_stmt(13) case_stmt(14) case_stmt(15)
29192  case_stmt(16) case_stmt(17) case_stmt(18) case_stmt(19)
29193  case_stmt(20) case_stmt(21) case_stmt(22) case_stmt(23)
29194  case_stmt(24) case_stmt(25) case_stmt(26) case_stmt(27)
29195  case_stmt(28) case_stmt(29) case_stmt(30)
29196  #undef case_stmt
29197  default : return error_node();
29198  }
29199  }
29200 
29201  template <typename T0, typename T1, typename T2>
29202  static inline bool compile(expression_generator<Type>& expr_gen, const std::string& id,
29203  T0 t0, T1 t1, T2 t2,
29204  expression_node_ptr& result)
29205  {
29206  details::operator_type sf3opr;
29207 
29208  if (!expr_gen.sf3_optimisable(id,sf3opr))
29209  return false;
29210  else
29211  result = synthesize_sf3ext_expression::template process<T0,T1,T2>(expr_gen,sf3opr,t0,t1,t2);
29212 
29213  return true;
29214  }
29215  };
29216 
29218  {
29219  template <typename T0, typename T1, typename T2, typename T3>
29221  const details::operator_type& sf4opr,
29222  T0 t0, T1 t1, T2 t2, T3 t3)
29223  {
29224  switch (sf4opr)
29225  {
29226  #define case_stmt0(op) \
29227  case details::e_sf##op : return details::T0oT1oT2oT3_sf4ext<Type,T0,T1,T2,T3,details::sf##op##_op<Type> >:: \
29228  allocate(*(expr_gen.node_allocator_), t0, t1, t2, t3); \
29229 
29230 
29231  #define case_stmt1(op) \
29232  case details::e_sf4ext##op : return details::T0oT1oT2oT3_sf4ext<Type,T0,T1,T2,T3,details::sfext##op##_op<Type> >:: \
29233  allocate(*(expr_gen.node_allocator_), t0, t1, t2, t3); \
29234 
29235  case_stmt0(48) case_stmt0(49) case_stmt0(50) case_stmt0(51)
29236  case_stmt0(52) case_stmt0(53) case_stmt0(54) case_stmt0(55)
29237  case_stmt0(56) case_stmt0(57) case_stmt0(58) case_stmt0(59)
29238  case_stmt0(60) case_stmt0(61) case_stmt0(62) case_stmt0(63)
29239  case_stmt0(64) case_stmt0(65) case_stmt0(66) case_stmt0(67)
29240  case_stmt0(68) case_stmt0(69) case_stmt0(70) case_stmt0(71)
29241  case_stmt0(72) case_stmt0(73) case_stmt0(74) case_stmt0(75)
29242  case_stmt0(76) case_stmt0(77) case_stmt0(78) case_stmt0(79)
29243  case_stmt0(80) case_stmt0(81) case_stmt0(82) case_stmt0(83)
29244 
29245  case_stmt1(00) case_stmt1(01) case_stmt1(02) case_stmt1(03)
29246  case_stmt1(04) case_stmt1(05) case_stmt1(06) case_stmt1(07)
29247  case_stmt1(08) case_stmt1(09) case_stmt1(10) case_stmt1(11)
29248  case_stmt1(12) case_stmt1(13) case_stmt1(14) case_stmt1(15)
29249  case_stmt1(16) case_stmt1(17) case_stmt1(18) case_stmt1(19)
29250  case_stmt1(20) case_stmt1(21) case_stmt1(22) case_stmt1(23)
29251  case_stmt1(24) case_stmt1(25) case_stmt1(26) case_stmt1(27)
29252  case_stmt1(28) case_stmt1(29) case_stmt1(30) case_stmt1(31)
29253  case_stmt1(32) case_stmt1(33) case_stmt1(34) case_stmt1(35)
29254  case_stmt1(36) case_stmt1(37) case_stmt1(38) case_stmt1(39)
29255  case_stmt1(40) case_stmt1(41) case_stmt1(42) case_stmt1(43)
29256  case_stmt1(44) case_stmt1(45) case_stmt1(46) case_stmt1(47)
29257  case_stmt1(48) case_stmt1(49) case_stmt1(50) case_stmt1(51)
29258  case_stmt1(52) case_stmt1(53) case_stmt1(54) case_stmt1(55)
29259  case_stmt1(56) case_stmt1(57) case_stmt1(58) case_stmt1(59)
29260  case_stmt1(60) case_stmt1(61)
29261 
29262  #undef case_stmt0
29263  #undef case_stmt1
29264  default : return error_node();
29265  }
29266  }
29267 
29268  template <typename T0, typename T1, typename T2, typename T3>
29269  static inline bool compile(expression_generator<Type>& expr_gen, const std::string& id,
29270  T0 t0, T1 t1, T2 t2, T3 t3,
29271  expression_node_ptr& result)
29272  {
29273  details::operator_type sf4opr;
29274 
29275  if (!expr_gen.sf4_optimisable(id,sf4opr))
29276  return false;
29277  else
29278  result = synthesize_sf4ext_expression::template process<T0,T1,T2,T3>
29279  (expr_gen, sf4opr, t0, t1, t2, t3);
29280 
29281  return true;
29282  }
29283 
29284  // T o (sf3ext)
29285  template <typename ExternalType>
29286  static inline bool compile_right(expression_generator<Type>& expr_gen,
29287  ExternalType t,
29288  const details::operator_type& operation,
29289  expression_node_ptr& sf3node,
29290  expression_node_ptr& result)
29291  {
29292  if (!details::is_sf3ext_node(sf3node))
29293  return false;
29294 
29295  typedef details::T0oT1oT2_base_node<Type>* sf3ext_base_ptr;
29296 
29297  sf3ext_base_ptr n = static_cast<sf3ext_base_ptr>(sf3node);
29298  std::string id = "t" + expr_gen.to_str(operation) + "(" + n->type_id() + ")";
29299 
29300  switch (n->type())
29301  {
29302  case details::expression_node<Type>::e_covoc : return compile_right_impl
29303  <typename covoc_t::sf3_type_node,ExternalType,ctype,vtype,ctype>
29304  (expr_gen, id, t, sf3node, result);
29305 
29306  case details::expression_node<Type>::e_covov : return compile_right_impl
29307  <typename covov_t::sf3_type_node,ExternalType,ctype,vtype,vtype>
29308  (expr_gen, id, t, sf3node, result);
29309 
29310  case details::expression_node<Type>::e_vocov : return compile_right_impl
29311  <typename vocov_t::sf3_type_node,ExternalType,vtype,ctype,vtype>
29312  (expr_gen, id, t, sf3node, result);
29313 
29314  case details::expression_node<Type>::e_vovoc : return compile_right_impl
29315  <typename vovoc_t::sf3_type_node,ExternalType,vtype,vtype,ctype>
29316  (expr_gen, id, t, sf3node, result);
29317 
29318  case details::expression_node<Type>::e_vovov : return compile_right_impl
29319  <typename vovov_t::sf3_type_node,ExternalType,vtype,vtype,vtype>
29320  (expr_gen, id, t, sf3node, result);
29321 
29322  default : return false;
29323  }
29324  }
29325 
29326  // (sf3ext) o T
29327  template <typename ExternalType>
29328  static inline bool compile_left(expression_generator<Type>& expr_gen,
29329  ExternalType t,
29330  const details::operator_type& operation,
29331  expression_node_ptr& sf3node,
29332  expression_node_ptr& result)
29333  {
29334  if (!details::is_sf3ext_node(sf3node))
29335  return false;
29336 
29337  typedef details::T0oT1oT2_base_node<Type>* sf3ext_base_ptr;
29338 
29339  sf3ext_base_ptr n = static_cast<sf3ext_base_ptr>(sf3node);
29340 
29341  std::string id = "(" + n->type_id() + ")" + expr_gen.to_str(operation) + "t";
29342 
29343  switch (n->type())
29344  {
29345  case details::expression_node<Type>::e_covoc : return compile_left_impl
29346  <typename covoc_t::sf3_type_node,ExternalType,ctype,vtype,ctype>
29347  (expr_gen, id, t, sf3node, result);
29348 
29349  case details::expression_node<Type>::e_covov : return compile_left_impl
29350  <typename covov_t::sf3_type_node,ExternalType,ctype,vtype,vtype>
29351  (expr_gen, id, t, sf3node, result);
29352 
29353  case details::expression_node<Type>::e_vocov : return compile_left_impl
29354  <typename vocov_t::sf3_type_node,ExternalType,vtype,ctype,vtype>
29355  (expr_gen, id, t, sf3node, result);
29356 
29357  case details::expression_node<Type>::e_vovoc : return compile_left_impl
29358  <typename vovoc_t::sf3_type_node,ExternalType,vtype,vtype,ctype>
29359  (expr_gen, id, t, sf3node, result);
29360 
29361  case details::expression_node<Type>::e_vovov : return compile_left_impl
29362  <typename vovov_t::sf3_type_node,ExternalType,vtype,vtype,vtype>
29363  (expr_gen, id, t, sf3node, result);
29364 
29365  default : return false;
29366  }
29367  }
29368 
29369  template <typename SF3TypeNode, typename ExternalType, typename T0, typename T1, typename T2>
29370  static inline bool compile_right_impl(expression_generator<Type>& expr_gen,
29371  const std::string& id,
29372  ExternalType t,
29373  expression_node_ptr& node,
29374  expression_node_ptr& result)
29375  {
29376  SF3TypeNode* n = dynamic_cast<SF3TypeNode*>(node);
29377 
29378  if (n)
29379  {
29380  T0 t0 = n->t0();
29381  T1 t1 = n->t1();
29382  T2 t2 = n->t2();
29383 
29384  return synthesize_sf4ext_expression::template compile<ExternalType,T0,T1,T2>
29385  (expr_gen, id, t, t0, t1, t2, result);
29386  }
29387  else
29388  return false;
29389  }
29390 
29391  template <typename SF3TypeNode, typename ExternalType, typename T0, typename T1, typename T2>
29392  static inline bool compile_left_impl(expression_generator<Type>& expr_gen,
29393  const std::string& id,
29394  ExternalType t,
29395  expression_node_ptr& node,
29396  expression_node_ptr& result)
29397  {
29398  SF3TypeNode* n = dynamic_cast<SF3TypeNode*>(node);
29399 
29400  if (n)
29401  {
29402  T0 t0 = n->t0();
29403  T1 t1 = n->t1();
29404  T2 t2 = n->t2();
29405 
29406  return synthesize_sf4ext_expression::template compile<T0,T1,T2,ExternalType>
29407  (expr_gen, id, t0, t1, t2, t, result);
29408  }
29409  else
29410  return false;
29411  }
29412  };
29413 
29415  {
29416  typedef typename vovov_t::type0 node_type;
29417  typedef typename vovov_t::sf3_type sf3_type;
29418 
29420  const details::operator_type& operation,
29421  expression_node_ptr (&branch)[2])
29422  {
29423  // (v0 o0 v1) o1 (v2)
29424  const details::vov_base_node<Type>* vov = static_cast<details::vov_base_node<Type>*>(branch[0]);
29425  const Type& v0 = vov->v0();
29426  const Type& v1 = vov->v1();
29427  const Type& v2 = static_cast<details::variable_node<Type>*>(branch[1])->ref();
29428  const details::operator_type o0 = vov->operation();
29429  const details::operator_type o1 = operation;
29430 
29431  binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
29432  binary_functor_t f1 = reinterpret_cast<binary_functor_t>(0);
29433 
29434  details::free_node(*(expr_gen.node_allocator_),branch[0]);
29435 
29436  expression_node_ptr result = error_node();
29437 
29439  {
29440  // (v0 / v1) / v2 --> (vovov) v0 / (v1 * v2)
29441  if ((details::e_div == o0) && (details::e_div == o1))
29442  {
29443  const bool synthesis_result =
29444  synthesize_sf3ext_expression::
29445  template compile<vtype,vtype,vtype>(expr_gen, "t/(t*t)", v0, v1, v2, result);
29446 
29447  exprtk_debug(("(v0 / v1) / v2 --> (vovov) v0 / (v1 * v2)\n"));
29448 
29449  return (synthesis_result) ? result : error_node();
29450  }
29451  }
29452 
29453  const bool synthesis_result =
29454  synthesize_sf3ext_expression::template compile<vtype, vtype, vtype>
29455  (expr_gen, id(expr_gen, o0, o1), v0, v1, v2, result);
29456 
29457  if (synthesis_result)
29458  return result;
29459  else if (!expr_gen.valid_operator(o0,f0))
29460  return error_node();
29461  else if (!expr_gen.valid_operator(o1,f1))
29462  return error_node();
29463  else
29464  return node_type::allocate(*(expr_gen.node_allocator_), v0, v1, v2, f0, f1);
29465  }
29466 
29467  static inline std::string id(expression_generator<Type>& expr_gen,
29469  {
29470  return (details::build_string() << "(t" << expr_gen.to_str(o0) << "t)" << expr_gen.to_str(o1) << "t");
29471  }
29472  };
29473 
29475  {
29476  typedef typename vovov_t::type1 node_type;
29477  typedef typename vovov_t::sf3_type sf3_type;
29478 
29480  const details::operator_type& operation,
29481  expression_node_ptr (&branch)[2])
29482  {
29483  // (v0) o0 (v1 o1 v2)
29484  const details::vov_base_node<Type>* vov = static_cast<details::vov_base_node<Type>*>(branch[1]);
29485  const Type& v0 = static_cast<details::variable_node<Type>*>(branch[0])->ref();
29486  const Type& v1 = vov->v0();
29487  const Type& v2 = vov->v1();
29488  const details::operator_type o0 = operation;
29489  const details::operator_type o1 = vov->operation();
29490 
29491  binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
29492  binary_functor_t f1 = reinterpret_cast<binary_functor_t>(0);
29493 
29494  details::free_node(*(expr_gen.node_allocator_),branch[1]);
29495 
29496  expression_node_ptr result = error_node();
29497 
29499  {
29500  // v0 / (v1 / v2) --> (vovov) (v0 * v2) / v1
29501  if ((details::e_div == o0) && (details::e_div == o1))
29502  {
29503  const bool synthesis_result =
29504  synthesize_sf3ext_expression::
29505  template compile<vtype,vtype,vtype>(expr_gen, "(t*t)/t", v0, v2, v1, result);
29506 
29507  exprtk_debug(("v0 / (v1 / v2) --> (vovov) (v0 * v2) / v1\n"));
29508 
29509  return (synthesis_result) ? result : error_node();
29510  }
29511  }
29512 
29513  const bool synthesis_result =
29514  synthesize_sf3ext_expression::template compile<vtype, vtype, vtype>
29515  (expr_gen, id(expr_gen, o0, o1), v0, v1, v2, result);
29516 
29517  if (synthesis_result)
29518  return result;
29519  else if (!expr_gen.valid_operator(o0,f0))
29520  return error_node();
29521  else if (!expr_gen.valid_operator(o1,f1))
29522  return error_node();
29523  else
29524  return node_type::allocate(*(expr_gen.node_allocator_), v0, v1, v2, f0, f1);
29525  }
29526 
29527  static inline std::string id(expression_generator<Type>& expr_gen,
29529  {
29530  return (details::build_string() << "t" << expr_gen.to_str(o0) << "(t" << expr_gen.to_str(o1) << "t)");
29531  }
29532  };
29533 
29535  {
29536  typedef typename vovoc_t::type0 node_type;
29537  typedef typename vovoc_t::sf3_type sf3_type;
29538 
29540  const details::operator_type& operation,
29541  expression_node_ptr (&branch)[2])
29542  {
29543  // (v0 o0 v1) o1 (c)
29544  const details::vov_base_node<Type>* vov = static_cast<details::vov_base_node<Type>*>(branch[0]);
29545  const Type& v0 = vov->v0();
29546  const Type& v1 = vov->v1();
29547  const Type c = static_cast<details::literal_node<Type>*>(branch[1])->value();
29548  const details::operator_type o0 = vov->operation();
29549  const details::operator_type o1 = operation;
29550 
29551  binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
29552  binary_functor_t f1 = reinterpret_cast<binary_functor_t>(0);
29553 
29554  details::free_node(*(expr_gen.node_allocator_),branch[0]);
29555  details::free_node(*(expr_gen.node_allocator_),branch[1]);
29556 
29557  expression_node_ptr result = error_node();
29558 
29560  {
29561  // (v0 / v1) / c --> (vovoc) v0 / (v1 * c)
29562  if ((details::e_div == o0) && (details::e_div == o1))
29563  {
29564  const bool synthesis_result =
29565  synthesize_sf3ext_expression::
29566  template compile<vtype,vtype,ctype>(expr_gen, "t/(t*t)", v0, v1, c, result);
29567 
29568  exprtk_debug(("(v0 / v1) / c --> (vovoc) v0 / (v1 * c)\n"));
29569 
29570  return (synthesis_result) ? result : error_node();
29571  }
29572  }
29573 
29574  const bool synthesis_result =
29575  synthesize_sf3ext_expression::template compile<vtype, vtype, ctype>
29576  (expr_gen, id(expr_gen, o0, o1), v0, v1, c, result);
29577 
29578  if (synthesis_result)
29579  return result;
29580  else if (!expr_gen.valid_operator(o0,f0))
29581  return error_node();
29582  else if (!expr_gen.valid_operator(o1,f1))
29583  return error_node();
29584  else
29585  return node_type::allocate(*(expr_gen.node_allocator_), v0, v1, c, f0, f1);
29586  }
29587 
29588  static inline std::string id(expression_generator<Type>& expr_gen,
29590  {
29591  return (details::build_string() << "(t" << expr_gen.to_str(o0) << "t)" << expr_gen.to_str(o1) << "t");
29592  }
29593  };
29594 
29596  {
29597  typedef typename vovoc_t::type1 node_type;
29598  typedef typename vovoc_t::sf3_type sf3_type;
29599 
29601  const details::operator_type& operation,
29602  expression_node_ptr (&branch)[2])
29603  {
29604  // (v0) o0 (v1 o1 c)
29605  const details::voc_base_node<Type>* voc = static_cast<const details::voc_base_node<Type>*>(branch[1]);
29606  const Type& v0 = static_cast<details::variable_node<Type>*>(branch[0])->ref();
29607  const Type& v1 = voc->v();
29608  const Type c = voc->c();
29609  const details::operator_type o0 = operation;
29610  const details::operator_type o1 = voc->operation();
29611 
29612  binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
29613  binary_functor_t f1 = reinterpret_cast<binary_functor_t>(0);
29614 
29615  details::free_node(*(expr_gen.node_allocator_),branch[1]);
29616 
29617  expression_node_ptr result = error_node();
29618 
29620  {
29621  // v0 / (v1 / c) --> (vocov) (v0 * c) / v1
29622  if ((details::e_div == o0) && (details::e_div == o1))
29623  {
29624  const bool synthesis_result =
29625  synthesize_sf3ext_expression::
29626  template compile<vtype,ctype,vtype>(expr_gen, "(t*t)/t", v0, c, v1, result);
29627 
29628  exprtk_debug(("v0 / (v1 / c) --> (vocov) (v0 * c) / v1\n"));
29629 
29630  return (synthesis_result) ? result : error_node();
29631  }
29632  }
29633 
29634  const bool synthesis_result =
29635  synthesize_sf3ext_expression::template compile<vtype, vtype, ctype>
29636  (expr_gen, id(expr_gen, o0, o1), v0, v1, c, result);
29637 
29638  if (synthesis_result)
29639  return result;
29640  else if (!expr_gen.valid_operator(o0,f0))
29641  return error_node();
29642  else if (!expr_gen.valid_operator(o1,f1))
29643  return error_node();
29644  else
29645  return node_type::allocate(*(expr_gen.node_allocator_), v0, v1, c, f0, f1);
29646  }
29647 
29648  static inline std::string id(expression_generator<Type>& expr_gen,
29650  {
29651  return (details::build_string() << "t" << expr_gen.to_str(o0) << "(t" << expr_gen.to_str(o1) << "t)");
29652  }
29653  };
29654 
29656  {
29657  typedef typename vocov_t::type0 node_type;
29658  typedef typename vocov_t::sf3_type sf3_type;
29659 
29661  const details::operator_type& operation,
29662  expression_node_ptr (&branch)[2])
29663  {
29664  // (v0 o0 c) o1 (v1)
29665  const details::voc_base_node<Type>* voc = static_cast<details::voc_base_node<Type>*>(branch[0]);
29666  const Type& v0 = voc->v();
29667  const Type c = voc->c();
29668  const Type& v1 = static_cast<details::variable_node<Type>*>(branch[1])->ref();
29669  const details::operator_type o0 = voc->operation();
29670  const details::operator_type o1 = operation;
29671 
29672  binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
29673  binary_functor_t f1 = reinterpret_cast<binary_functor_t>(0);
29674 
29675  details::free_node(*(expr_gen.node_allocator_),branch[0]);
29676 
29677  expression_node_ptr result = error_node();
29678 
29680  {
29681  // (v0 / c) / v1 --> (vovoc) v0 / (v1 * c)
29682  if ((details::e_div == o0) && (details::e_div == o1))
29683  {
29684  const bool synthesis_result =
29685  synthesize_sf3ext_expression::
29686  template compile<vtype,vtype,ctype>(expr_gen, "t/(t*t)", v0, v1, c, result);
29687 
29688  exprtk_debug(("(v0 / c) / v1 --> (vovoc) v0 / (v1 * c)\n"));
29689 
29690  return (synthesis_result) ? result : error_node();
29691  }
29692  }
29693 
29694  const bool synthesis_result =
29695  synthesize_sf3ext_expression::template compile<vtype, ctype, vtype>
29696  (expr_gen, id(expr_gen, o0, o1), v0, c, v1, result);
29697 
29698  if (synthesis_result)
29699  return result;
29700  else if (!expr_gen.valid_operator(o0,f0))
29701  return error_node();
29702  else if (!expr_gen.valid_operator(o1,f1))
29703  return error_node();
29704  else
29705  return node_type::allocate(*(expr_gen.node_allocator_), v0, c, v1, f0, f1);
29706  }
29707 
29708  static inline std::string id(expression_generator<Type>& expr_gen,
29710  {
29711  return (details::build_string() << "(t" << expr_gen.to_str(o0) << "t)" << expr_gen.to_str(o1) << "t");
29712  }
29713  };
29714 
29716  {
29717  typedef typename vocov_t::type1 node_type;
29718  typedef typename vocov_t::sf3_type sf3_type;
29719 
29721  const details::operator_type& operation,
29722  expression_node_ptr (&branch)[2])
29723  {
29724  // (v0) o0 (c o1 v1)
29725  const details::cov_base_node<Type>* cov = static_cast<details::cov_base_node<Type>*>(branch[1]);
29726  const Type& v0 = static_cast<details::variable_node<Type>*>(branch[0])->ref();
29727  const Type c = cov->c();
29728  const Type& v1 = cov->v();
29729  const details::operator_type o0 = operation;
29730  const details::operator_type o1 = cov->operation();
29731 
29732  binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
29733  binary_functor_t f1 = reinterpret_cast<binary_functor_t>(0);
29734 
29735  details::free_node(*(expr_gen.node_allocator_),branch[1]);
29736 
29737  expression_node_ptr result = error_node();
29738 
29740  {
29741  // v0 / (c / v1) --> (vovoc) (v0 * v1) / c
29742  if ((details::e_div == o0) && (details::e_div == o1))
29743  {
29744  const bool synthesis_result =
29745  synthesize_sf3ext_expression::
29746  template compile<vtype, vtype, ctype>(expr_gen, "(t*t)/t", v0, v1, c, result);
29747 
29748  exprtk_debug(("v0 / (c / v1) --> (vovoc) (v0 * v1) / c\n"));
29749 
29750  return (synthesis_result) ? result : error_node();
29751  }
29752  }
29753 
29754  const bool synthesis_result =
29755  synthesize_sf3ext_expression::template compile<vtype, ctype, vtype>
29756  (expr_gen, id(expr_gen, o0, o1), v0, c, v1, result);
29757 
29758  if (synthesis_result)
29759  return result;
29760  else if (!expr_gen.valid_operator(o0,f0))
29761  return error_node();
29762  else if (!expr_gen.valid_operator(o1,f1))
29763  return error_node();
29764  else
29765  return node_type::allocate(*(expr_gen.node_allocator_), v0, c, v1, f0, f1);
29766  }
29767 
29768  static inline std::string id(expression_generator<Type>& expr_gen,
29770  {
29771  return (details::build_string() << "t" << expr_gen.to_str(o0) << "(t" << expr_gen.to_str(o1) << "t)");
29772  }
29773  };
29774 
29776  {
29777  typedef typename covov_t::type0 node_type;
29778  typedef typename covov_t::sf3_type sf3_type;
29779 
29781  const details::operator_type& operation,
29782  expression_node_ptr (&branch)[2])
29783  {
29784  // (c o0 v0) o1 (v1)
29785  const details::cov_base_node<Type>* cov = static_cast<details::cov_base_node<Type>*>(branch[0]);
29786  const Type c = cov->c();
29787  const Type& v0 = cov->v();
29788  const Type& v1 = static_cast<details::variable_node<Type>*>(branch[1])->ref();
29789  const details::operator_type o0 = cov->operation();
29790  const details::operator_type o1 = operation;
29791 
29792  binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
29793  binary_functor_t f1 = reinterpret_cast<binary_functor_t>(0);
29794 
29795  details::free_node(*(expr_gen.node_allocator_),branch[0]);
29796 
29797  expression_node_ptr result = error_node();
29798 
29800  {
29801  // (c / v0) / v1 --> (covov) c / (v0 * v1)
29802  if ((details::e_div == o0) && (details::e_div == o1))
29803  {
29804  const bool synthesis_result =
29805  synthesize_sf3ext_expression::
29806  template compile<ctype, vtype, vtype>(expr_gen, "t/(t*t)", c, v0, v1, result);
29807 
29808  exprtk_debug(("(c / v0) / v1 --> (covov) c / (v0 * v1)\n"));
29809 
29810  return (synthesis_result) ? result : error_node();
29811  }
29812  }
29813 
29814  const bool synthesis_result =
29815  synthesize_sf3ext_expression::template compile<ctype, vtype, vtype>
29816  (expr_gen, id(expr_gen, o0, o1), c, v0, v1, result);
29817 
29818  if (synthesis_result)
29819  return result;
29820  else if (!expr_gen.valid_operator(o0,f0))
29821  return error_node();
29822  else if (!expr_gen.valid_operator(o1,f1))
29823  return error_node();
29824  else
29825  return node_type::allocate(*(expr_gen.node_allocator_), c, v0, v1, f0, f1);
29826  }
29827 
29828  static inline std::string id(expression_generator<Type>& expr_gen,
29830  {
29831  return (details::build_string() << "(t" << expr_gen.to_str(o0) << "t)" << expr_gen.to_str(o1) << "t");
29832  }
29833  };
29834 
29836  {
29837  typedef typename covov_t::type1 node_type;
29838  typedef typename covov_t::sf3_type sf3_type;
29839 
29841  const details::operator_type& operation,
29842  expression_node_ptr (&branch)[2])
29843  {
29844  // (c) o0 (v0 o1 v1)
29845  const details::vov_base_node<Type>* vov = static_cast<details::vov_base_node<Type>*>(branch[1]);
29846  const Type c = static_cast<details::literal_node<Type>*>(branch[0])->value();
29847  const Type& v0 = vov->v0();
29848  const Type& v1 = vov->v1();
29849  const details::operator_type o0 = operation;
29850  const details::operator_type o1 = vov->operation();
29851 
29852  binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
29853  binary_functor_t f1 = reinterpret_cast<binary_functor_t>(0);
29854 
29855  details::free_node(*(expr_gen.node_allocator_),branch[0]);
29856  details::free_node(*(expr_gen.node_allocator_),branch[1]);
29857 
29858  expression_node_ptr result = error_node();
29859 
29861  {
29862  // c / (v0 / v1) --> (covov) (c * v1) / v0
29863  if ((details::e_div == o0) && (details::e_div == o1))
29864  {
29865  const bool synthesis_result =
29866  synthesize_sf3ext_expression::
29867  template compile<ctype, vtype, vtype>(expr_gen, "(t*t)/t", c, v1, v0, result);
29868 
29869  exprtk_debug(("c / (v0 / v1) --> (covov) (c * v1) / v0\n"));
29870 
29871  return (synthesis_result) ? result : error_node();
29872  }
29873  }
29874 
29875  const bool synthesis_result =
29876  synthesize_sf3ext_expression::template compile<ctype, vtype, vtype>
29877  (expr_gen, id(expr_gen, o0, o1), c, v0, v1, result);
29878 
29879  if (synthesis_result)
29880  return result;
29881  else if (!expr_gen.valid_operator(o0,f0))
29882  return error_node();
29883  else if (!expr_gen.valid_operator(o1,f1))
29884  return error_node();
29885  else
29886  return node_type::allocate(*(expr_gen.node_allocator_), c, v0, v1, f0, f1);
29887  }
29888 
29889  static inline std::string id(expression_generator<Type>& expr_gen, const details::operator_type o0, const details::operator_type o1)
29890  {
29891  return (details::build_string() << "t" << expr_gen.to_str(o0) << "(t" << expr_gen.to_str(o1) << "t)");
29892  }
29893  };
29894 
29896  {
29897  typedef typename covoc_t::type0 node_type;
29898  typedef typename covoc_t::sf3_type sf3_type;
29899 
29901  const details::operator_type& operation,
29902  expression_node_ptr (&branch)[2])
29903  {
29904  // (c0 o0 v) o1 (c1)
29905  const details::cov_base_node<Type>* cov = static_cast<details::cov_base_node<Type>*>(branch[0]);
29906  const Type c0 = cov->c();
29907  const Type& v = cov->v();
29908  const Type c1 = static_cast<details::literal_node<Type>*>(branch[1])->value();
29909  const details::operator_type o0 = cov->operation();
29910  const details::operator_type o1 = operation;
29911 
29912  binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
29913  binary_functor_t f1 = reinterpret_cast<binary_functor_t>(0);
29914 
29915  details::free_node(*(expr_gen.node_allocator_),branch[0]);
29916  details::free_node(*(expr_gen.node_allocator_),branch[1]);
29917 
29918  expression_node_ptr result = error_node();
29919 
29921  {
29922  // (c0 + v) + c1 --> (cov) (c0 + c1) + v
29923  if ((details::e_add == o0) && (details::e_add == o1))
29924  {
29925  exprtk_debug(("(c0 + v) + c1 --> (cov) (c0 + c1) + v\n"));
29926 
29927  return expr_gen.node_allocator_->
29928  template allocate_cr<typename details::cov_node<Type,details::add_op<Type> > >(c0 + c1, v);
29929  }
29930  // (c0 + v) - c1 --> (cov) (c0 - c1) + v
29931  else if ((details::e_add == o0) && (details::e_sub == o1))
29932  {
29933  exprtk_debug(("(c0 + v) - c1 --> (cov) (c0 - c1) + v\n"));
29934 
29935  return expr_gen.node_allocator_->
29936  template allocate_cr<typename details::cov_node<Type,details::add_op<Type> > >(c0 - c1, v);
29937  }
29938  // (c0 - v) + c1 --> (cov) (c0 + c1) - v
29939  else if ((details::e_sub == o0) && (details::e_add == o1))
29940  {
29941  exprtk_debug(("(c0 - v) + c1 --> (cov) (c0 + c1) - v\n"));
29942 
29943  return expr_gen.node_allocator_->
29944  template allocate_cr<typename details::cov_node<Type,details::sub_op<Type> > >(c0 + c1, v);
29945  }
29946  // (c0 - v) - c1 --> (cov) (c0 - c1) - v
29947  else if ((details::e_sub == o0) && (details::e_sub == o1))
29948  {
29949  exprtk_debug(("(c0 - v) - c1 --> (cov) (c0 - c1) - v\n"));
29950 
29951  return expr_gen.node_allocator_->
29952  template allocate_cr<typename details::cov_node<Type,details::sub_op<Type> > >(c0 - c1, v);
29953  }
29954  // (c0 * v) * c1 --> (cov) (c0 * c1) * v
29955  else if ((details::e_mul == o0) && (details::e_mul == o1))
29956  {
29957  exprtk_debug(("(c0 * v) * c1 --> (cov) (c0 * c1) * v\n"));
29958 
29959  return expr_gen.node_allocator_->
29960  template allocate_cr<typename details::cov_node<Type,details::mul_op<Type> > >(c0 * c1, v);
29961  }
29962  // (c0 * v) / c1 --> (cov) (c0 / c1) * v
29963  else if ((details::e_mul == o0) && (details::e_div == o1))
29964  {
29965  exprtk_debug(("(c0 * v) / c1 --> (cov) (c0 / c1) * v\n"));
29966 
29967  return expr_gen.node_allocator_->
29968  template allocate_cr<typename details::cov_node<Type,details::mul_op<Type> > >(c0 / c1, v);
29969  }
29970  // (c0 / v) * c1 --> (cov) (c0 * c1) / v
29971  else if ((details::e_div == o0) && (details::e_mul == o1))
29972  {
29973  exprtk_debug(("(c0 / v) * c1 --> (cov) (c0 * c1) / v\n"));
29974 
29975  return expr_gen.node_allocator_->
29976  template allocate_cr<typename details::cov_node<Type,details::div_op<Type> > >(c0 * c1, v);
29977  }
29978  // (c0 / v) / c1 --> (cov) (c0 / c1) / v
29979  else if ((details::e_div == o0) && (details::e_div == o1))
29980  {
29981  exprtk_debug(("(c0 / v) / c1 --> (cov) (c0 / c1) / v\n"));
29982 
29983  return expr_gen.node_allocator_->
29984  template allocate_cr<typename details::cov_node<Type,details::div_op<Type> > >(c0 / c1, v);
29985  }
29986  }
29987 
29988  const bool synthesis_result =
29989  synthesize_sf3ext_expression::template compile<ctype, vtype, ctype>
29990  (expr_gen, id(expr_gen, o0, o1), c0, v, c1,result);
29991 
29992  if (synthesis_result)
29993  return result;
29994  else if (!expr_gen.valid_operator(o0,f0))
29995  return error_node();
29996  else if (!expr_gen.valid_operator(o1,f1))
29997  return error_node();
29998  else
29999  return node_type::allocate(*(expr_gen.node_allocator_), c0, v, c1, f0, f1);
30000  }
30001 
30002  static inline std::string id(expression_generator<Type>& expr_gen,
30004  {
30005  return (details::build_string() << "(t" << expr_gen.to_str(o0) << "t)" << expr_gen.to_str(o1) << "t");
30006  }
30007  };
30008 
30010  {
30011  typedef typename covoc_t::type1 node_type;
30012  typedef typename covoc_t::sf3_type sf3_type;
30013 
30015  const details::operator_type& operation,
30016  expression_node_ptr (&branch)[2])
30017  {
30018  // (c0) o0 (v o1 c1)
30019  const details::voc_base_node<Type>* voc = static_cast<details::voc_base_node<Type>*>(branch[1]);
30020  const Type c0 = static_cast<details::literal_node<Type>*>(branch[0])->value();
30021  const Type& v = voc->v();
30022  const Type c1 = voc->c();
30023  const details::operator_type o0 = operation;
30024  const details::operator_type o1 = voc->operation();
30025 
30026  binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
30027  binary_functor_t f1 = reinterpret_cast<binary_functor_t>(0);
30028 
30029  details::free_node(*(expr_gen.node_allocator_),branch[0]);
30030  details::free_node(*(expr_gen.node_allocator_),branch[1]);
30031 
30032  expression_node_ptr result = error_node();
30033 
30035  {
30036  // (c0) + (v + c1) --> (cov) (c0 + c1) + v
30037  if ((details::e_add == o0) && (details::e_add == o1))
30038  {
30039  exprtk_debug(("(c0) + (v + c1) --> (cov) (c0 + c1) + v\n"));
30040 
30041  return expr_gen.node_allocator_->
30042  template allocate_cr<typename details::cov_node<Type,details::add_op<Type> > >(c0 + c1, v);
30043  }
30044  // (c0) + (v - c1) --> (cov) (c0 - c1) + v
30045  else if ((details::e_add == o0) && (details::e_sub == o1))
30046  {
30047  exprtk_debug(("(c0) + (v - c1) --> (cov) (c0 - c1) + v\n"));
30048 
30049  return expr_gen.node_allocator_->
30050  template allocate_cr<typename details::cov_node<Type,details::add_op<Type> > >(c0 - c1, v);
30051  }
30052  // (c0) - (v + c1) --> (cov) (c0 - c1) - v
30053  else if ((details::e_sub == o0) && (details::e_add == o1))
30054  {
30055  exprtk_debug(("(c0) - (v + c1) --> (cov) (c0 - c1) - v\n"));
30056 
30057  return expr_gen.node_allocator_->
30058  template allocate_cr<typename details::cov_node<Type,details::sub_op<Type> > >(c0 - c1, v);
30059  }
30060  // (c0) - (v - c1) --> (cov) (c0 + c1) - v
30061  else if ((details::e_sub == o0) && (details::e_sub == o1))
30062  {
30063  exprtk_debug(("(c0) - (v - c1) --> (cov) (c0 + c1) - v\n"));
30064 
30065  return expr_gen.node_allocator_->
30066  template allocate_cr<typename details::cov_node<Type,details::sub_op<Type> > >(c0 + c1, v);
30067  }
30068  // (c0) * (v * c1) --> (voc) v * (c0 * c1)
30069  else if ((details::e_mul == o0) && (details::e_mul == o1))
30070  {
30071  exprtk_debug(("(c0) * (v * c1) --> (voc) v * (c0 * c1)\n"));
30072 
30073  return expr_gen.node_allocator_->
30074  template allocate_cr<typename details::cov_node<Type,details::mul_op<Type> > >(c0 * c1, v);
30075  }
30076  // (c0) * (v / c1) --> (cov) (c0 / c1) * v
30077  else if ((details::e_mul == o0) && (details::e_div == o1))
30078  {
30079  exprtk_debug(("(c0) * (v / c1) --> (cov) (c0 / c1) * v\n"));
30080 
30081  return expr_gen.node_allocator_->
30082  template allocate_cr<typename details::cov_node<Type,details::mul_op<Type> > >(c0 / c1, v);
30083  }
30084  // (c0) / (v * c1) --> (cov) (c0 / c1) / v
30085  else if ((details::e_div == o0) && (details::e_mul == o1))
30086  {
30087  exprtk_debug(("(c0) / (v * c1) --> (cov) (c0 / c1) / v\n"));
30088 
30089  return expr_gen.node_allocator_->
30090  template allocate_cr<typename details::cov_node<Type,details::div_op<Type> > >(c0 / c1, v);
30091  }
30092  // (c0) / (v / c1) --> (cov) (c0 * c1) / v
30093  else if ((details::e_div == o0) && (details::e_div == o1))
30094  {
30095  exprtk_debug(("(c0) / (v / c1) --> (cov) (c0 * c1) / v\n"));
30096 
30097  return expr_gen.node_allocator_->
30098  template allocate_cr<typename details::cov_node<Type,details::div_op<Type> > >(c0 * c1, v);
30099  }
30100  }
30101 
30102  const bool synthesis_result =
30103  synthesize_sf3ext_expression::template compile<ctype, vtype, ctype>
30104  (expr_gen, id(expr_gen, o0, o1), c0, v, c1, result);
30105 
30106  if (synthesis_result)
30107  return result;
30108  else if (!expr_gen.valid_operator(o0,f0))
30109  return error_node();
30110  else if (!expr_gen.valid_operator(o1,f1))
30111  return error_node();
30112  else
30113  return node_type::allocate(*(expr_gen.node_allocator_), c0, v, c1, f0, f1);
30114  }
30115 
30116  static inline std::string id(expression_generator<Type>& expr_gen,
30118  {
30119  return (details::build_string() << "t" << expr_gen.to_str(o0) << "(t" << expr_gen.to_str(o1) << "t)");
30120  }
30121  };
30122 
30124  {
30125  typedef typename cocov_t::type0 node_type;
30127  {
30128  // (c0 o0 c1) o1 (v) - Not possible.
30129  return error_node();
30130  }
30131  };
30132 
30134  {
30135  typedef typename cocov_t::type1 node_type;
30136  typedef typename cocov_t::sf3_type sf3_type;
30137 
30139  const details::operator_type& operation,
30140  expression_node_ptr (&branch)[2])
30141  {
30142  // (c0) o0 (c1 o1 v)
30143  const details::cov_base_node<Type>* cov = static_cast<details::cov_base_node<Type>*>(branch[1]);
30144  const Type c0 = static_cast<details::literal_node<Type>*>(branch[0])->value();
30145  const Type c1 = cov->c();
30146  const Type& v = cov->v();
30147  const details::operator_type o0 = operation;
30148  const details::operator_type o1 = cov->operation();
30149 
30150  binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
30151  binary_functor_t f1 = reinterpret_cast<binary_functor_t>(0);
30152 
30153  details::free_node(*(expr_gen.node_allocator_),branch[0]);
30154  details::free_node(*(expr_gen.node_allocator_),branch[1]);
30155 
30156  expression_node_ptr result = error_node();
30157 
30159  {
30160  // (c0) + (c1 + v) --> (cov) (c0 + c1) + v
30161  if ((details::e_add == o0) && (details::e_add == o1))
30162  {
30163  exprtk_debug(("(c0) + (c1 + v) --> (cov) (c0 + c1) + v\n"));
30164 
30165  return expr_gen.node_allocator_->
30166  template allocate_cr<typename details::cov_node<Type,details::add_op<Type> > >(c0 + c1, v);
30167  }
30168  // (c0) + (c1 - v) --> (cov) (c0 + c1) - v
30169  else if ((details::e_add == o0) && (details::e_sub == o1))
30170  {
30171  exprtk_debug(("(c0) + (c1 - v) --> (cov) (c0 + c1) - v\n"));
30172 
30173  return expr_gen.node_allocator_->
30174  template allocate_cr<typename details::cov_node<Type,details::sub_op<Type> > >(c0 + c1, v);
30175  }
30176  // (c0) - (c1 + v) --> (cov) (c0 - c1) - v
30177  else if ((details::e_sub == o0) && (details::e_add == o1))
30178  {
30179  exprtk_debug(("(c0) - (c1 + v) --> (cov) (c0 - c1) - v\n"));
30180 
30181  return expr_gen.node_allocator_->
30182  template allocate_cr<typename details::cov_node<Type,details::sub_op<Type> > >(c0 - c1, v);
30183  }
30184  // (c0) - (c1 - v) --> (cov) (c0 - c1) + v
30185  else if ((details::e_sub == o0) && (details::e_sub == o1))
30186  {
30187  exprtk_debug(("(c0) - (c1 - v) --> (cov) (c0 - c1) + v\n"));
30188 
30189  return expr_gen.node_allocator_->
30190  template allocate_cr<typename details::cov_node<Type,details::add_op<Type> > >(c0 - c1, v);
30191  }
30192  // (c0) * (c1 * v) --> (cov) (c0 * c1) * v
30193  else if ((details::e_mul == o0) && (details::e_mul == o1))
30194  {
30195  exprtk_debug(("(c0) * (c1 * v) --> (cov) (c0 * c1) * v\n"));
30196 
30197  return expr_gen.node_allocator_->
30198  template allocate_cr<typename details::cov_node<Type,details::mul_op<Type> > >(c0 * c1, v);
30199  }
30200  // (c0) * (c1 / v) --> (cov) (c0 * c1) / v
30201  else if ((details::e_mul == o0) && (details::e_div == o1))
30202  {
30203  exprtk_debug(("(c0) * (c1 / v) --> (cov) (c0 * c1) / v\n"));
30204 
30205  return expr_gen.node_allocator_->
30206  template allocate_cr<typename details::cov_node<Type,details::div_op<Type> > >(c0 * c1, v);
30207  }
30208  // (c0) / (c1 * v) --> (cov) (c0 / c1) / v
30209  else if ((details::e_div == o0) && (details::e_mul == o1))
30210  {
30211  exprtk_debug(("(c0) / (c1 * v) --> (cov) (c0 / c1) / v\n"));
30212 
30213  return expr_gen.node_allocator_->
30214  template allocate_cr<typename details::cov_node<Type,details::div_op<Type> > >(c0 / c1, v);
30215  }
30216  // (c0) / (c1 / v) --> (cov) (c0 / c1) * v
30217  else if ((details::e_div == o0) && (details::e_div == o1))
30218  {
30219  exprtk_debug(("(c0) / (c1 / v) --> (cov) (c0 / c1) * v\n"));
30220 
30221  return expr_gen.node_allocator_->
30222  template allocate_cr<typename details::cov_node<Type,details::mul_op<Type> > >(c0 / c1, v);
30223  }
30224  }
30225 
30226  const bool synthesis_result =
30227  synthesize_sf3ext_expression::template compile<ctype, ctype, vtype>
30228  (expr_gen, id(expr_gen, o0, o1), c0, c1, v, result);
30229 
30230  if (synthesis_result)
30231  return result;
30232  else if (!expr_gen.valid_operator(o0,f0))
30233  return error_node();
30234  else if (!expr_gen.valid_operator(o1,f1))
30235  return error_node();
30236  else
30237  return node_type::allocate(*(expr_gen.node_allocator_), c0, c1, v, f0, f1);
30238  }
30239 
30240  static inline std::string id(expression_generator<Type>& expr_gen, const details::operator_type o0, const details::operator_type o1)
30241  {
30242  return (details::build_string() << "t" << expr_gen.to_str(o0) << "(t" << expr_gen.to_str(o1) << "t)");
30243  }
30244  };
30245 
30247  {
30248  typedef typename vococ_t::type0 node_type;
30249  typedef typename vococ_t::sf3_type sf3_type;
30250 
30252  const details::operator_type& operation,
30253  expression_node_ptr (&branch)[2])
30254  {
30255  // (v o0 c0) o1 (c1)
30256  const details::voc_base_node<Type>* voc = static_cast<details::voc_base_node<Type>*>(branch[0]);
30257  const Type& v = voc->v();
30258  const Type& c0 = voc->c();
30259  const Type& c1 = static_cast<details::literal_node<Type>*>(branch[1])->value();
30260  const details::operator_type o0 = voc->operation();
30261  const details::operator_type o1 = operation;
30262 
30263  binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
30264  binary_functor_t f1 = reinterpret_cast<binary_functor_t>(0);
30265 
30266  details::free_node(*(expr_gen.node_allocator_),branch[0]);
30267  details::free_node(*(expr_gen.node_allocator_),branch[1]);
30268 
30269  expression_node_ptr result = error_node();
30270 
30272  {
30273  // (v + c0) + c1 --> (voc) v + (c0 + c1)
30274  if ((details::e_add == o0) && (details::e_add == o1))
30275  {
30276  exprtk_debug(("(v + c0) + c1 --> (voc) v + (c0 + c1)\n"));
30277 
30278  return expr_gen.node_allocator_->
30279  template allocate_rc<typename details::voc_node<Type,details::add_op<Type> > >(v, c0 + c1);
30280  }
30281  // (v + c0) - c1 --> (voc) v + (c0 - c1)
30282  else if ((details::e_add == o0) && (details::e_sub == o1))
30283  {
30284  exprtk_debug(("(v + c0) - c1 --> (voc) v + (c0 - c1)\n"));
30285 
30286  return expr_gen.node_allocator_->
30287  template allocate_rc<typename details::voc_node<Type,details::add_op<Type> > >(v, c0 - c1);
30288  }
30289  // (v - c0) + c1 --> (voc) v - (c0 + c1)
30290  else if ((details::e_sub == o0) && (details::e_add == o1))
30291  {
30292  exprtk_debug(("(v - c0) + c1 --> (voc) v - (c0 + c1)\n"));
30293 
30294  return expr_gen.node_allocator_->
30295  template allocate_rc<typename details::voc_node<Type,details::add_op<Type> > >(v, c1 - c0);
30296  }
30297  // (v - c0) - c1 --> (voc) v - (c0 + c1)
30298  else if ((details::e_sub == o0) && (details::e_sub == o1))
30299  {
30300  exprtk_debug(("(v - c0) - c1 --> (voc) v - (c0 + c1)\n"));
30301 
30302  return expr_gen.node_allocator_->
30303  template allocate_rc<typename details::voc_node<Type,details::sub_op<Type> > >(v, c0 + c1);
30304  }
30305  // (v * c0) * c1 --> (voc) v * (c0 * c1)
30306  else if ((details::e_mul == o0) && (details::e_mul == o1))
30307  {
30308  exprtk_debug(("(v * c0) * c1 --> (voc) v * (c0 * c1)\n"));
30309 
30310  return expr_gen.node_allocator_->
30311  template allocate_rc<typename details::voc_node<Type,details::mul_op<Type> > >(v, c0 * c1);
30312  }
30313  // (v * c0) / c1 --> (voc) v * (c0 / c1)
30314  else if ((details::e_mul == o0) && (details::e_div == o1))
30315  {
30316  exprtk_debug(("(v * c0) / c1 --> (voc) v * (c0 / c1)\n"));
30317 
30318  return expr_gen.node_allocator_->
30319  template allocate_rc<typename details::voc_node<Type,details::mul_op<Type> > >(v, c0 / c1);
30320  }
30321  // (v / c0) * c1 --> (voc) v * (c1 / c0)
30322  else if ((details::e_div == o0) && (details::e_mul == o1))
30323  {
30324  exprtk_debug(("(v / c0) * c1 --> (voc) v * (c1 / c0)\n"));
30325 
30326  return expr_gen.node_allocator_->
30327  template allocate_rc<typename details::voc_node<Type,details::mul_op<Type> > >(v, c1 / c0);
30328  }
30329  // (v / c0) / c1 --> (voc) v / (c0 * c1)
30330  else if ((details::e_div == o0) && (details::e_div == o1))
30331  {
30332  exprtk_debug(("(v / c0) / c1 --> (voc) v / (c0 * c1)\n"));
30333 
30334  return expr_gen.node_allocator_->
30335  template allocate_rc<typename details::voc_node<Type,details::div_op<Type> > >(v, c0 * c1);
30336  }
30337  // (v ^ c0) ^ c1 --> (voc) v ^ (c0 * c1)
30338  else if ((details::e_pow == o0) && (details::e_pow == o1))
30339  {
30340  exprtk_debug(("(v ^ c0) ^ c1 --> (voc) v ^ (c0 * c1)\n"));
30341 
30342  return expr_gen.node_allocator_->
30343  template allocate_rc<typename details::voc_node<Type,details::pow_op<Type> > >(v, c0 * c1);
30344  }
30345  }
30346 
30347  const bool synthesis_result =
30348  synthesize_sf3ext_expression::template compile<vtype, ctype, ctype>
30349  (expr_gen, id(expr_gen, o0, o1), v, c0, c1, result);
30350 
30351  if (synthesis_result)
30352  return result;
30353  else if (!expr_gen.valid_operator(o0,f0))
30354  return error_node();
30355  else if (!expr_gen.valid_operator(o1,f1))
30356  return error_node();
30357  else
30358  return node_type::allocate(*(expr_gen.node_allocator_), v, c0, c1, f0, f1);
30359  }
30360 
30361  static inline std::string id(expression_generator<Type>& expr_gen,
30363  {
30364  return (details::build_string() << "(t" << expr_gen.to_str(o0) << "t)" << expr_gen.to_str(o1) << "t");
30365  }
30366  };
30367 
30369  {
30370  typedef typename vococ_t::type0 node_type;
30371 
30373  {
30374  // (v) o0 (c0 o1 c1) - Not possible.
30375  exprtk_debug(("(v) o0 (c0 o1 c1) - Not possible.\n"));
30376  return error_node();
30377  }
30378  };
30379 
30381  {
30382  typedef typename vovovov_t::type0 node_type;
30383  typedef typename vovovov_t::sf4_type sf4_type;
30384  typedef typename node_type::T0 T0;
30385  typedef typename node_type::T1 T1;
30386  typedef typename node_type::T2 T2;
30387  typedef typename node_type::T3 T3;
30388 
30390  const details::operator_type& operation,
30391  expression_node_ptr (&branch)[2])
30392  {
30393  // (v0 o0 v1) o1 (v2 o2 v3)
30394  const details::vov_base_node<Type>* vov0 = static_cast<details::vov_base_node<Type>*>(branch[0]);
30395  const details::vov_base_node<Type>* vov1 = static_cast<details::vov_base_node<Type>*>(branch[1]);
30396  const Type& v0 = vov0->v0();
30397  const Type& v1 = vov0->v1();
30398  const Type& v2 = vov1->v0();
30399  const Type& v3 = vov1->v1();
30400  const details::operator_type o0 = vov0->operation();
30401  const details::operator_type o1 = operation;
30402  const details::operator_type o2 = vov1->operation();
30403 
30404  binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
30405  binary_functor_t f1 = reinterpret_cast<binary_functor_t>(0);
30406  binary_functor_t f2 = reinterpret_cast<binary_functor_t>(0);
30407 
30408  details::free_node(*(expr_gen.node_allocator_),branch[0]);
30409  details::free_node(*(expr_gen.node_allocator_),branch[1]);
30410 
30411  expression_node_ptr result = error_node();
30412 
30414  {
30415  // (v0 / v1) * (v2 / v3) --> (vovovov) (v0 * v2) / (v1 * v3)
30416  if ((details::e_div == o0) && (details::e_mul == o1) && (details::e_div == o2))
30417  {
30418  const bool synthesis_result =
30419  synthesize_sf4ext_expression::
30420  template compile<vtype,vtype,vtype,vtype>(expr_gen, "(t*t)/(t*t)", v0, v2, v1, v3, result);
30421 
30422  exprtk_debug(("(v0 / v1) * (v2 / v3) --> (vovovov) (v0 * v2) / (v1 * v3)\n"));
30423 
30424  return (synthesis_result) ? result : error_node();
30425  }
30426  // (v0 / v1) / (v2 / v3) --> (vovovov) (v0 * v3) / (v1 * v2)
30427  else if ((details::e_div == o0) && (details::e_div == o1) && (details::e_div == o2))
30428  {
30429  const bool synthesis_result =
30430  synthesize_sf4ext_expression::
30431  template compile<vtype,vtype,vtype,vtype>(expr_gen, "(t*t)/(t*t)", v0, v3, v1, v2, result);
30432 
30433  exprtk_debug(("(v0 / v1) / (v2 / v3) --> (vovovov) (v0 * v3) / (v1 * v2)\n"));
30434 
30435  return (synthesis_result) ? result : error_node();
30436  }
30437  // (v0 + v1) / (v2 / v3) --> (vovovov) (v0 + v1) * (v3 / v2)
30438  else if ((details::e_add == o0) && (details::e_div == o1) && (details::e_div == o2))
30439  {
30440  const bool synthesis_result =
30441  synthesize_sf4ext_expression::
30442  template compile<vtype,vtype,vtype,vtype>(expr_gen, "(t+t)*(t/t)", v0, v1, v3, v2, result);
30443 
30444  exprtk_debug(("(v0 + v1) / (v2 / v3) --> (vovovov) (v0 + v1) * (v3 / v2)\n"));
30445 
30446  return (synthesis_result) ? result : error_node();
30447  }
30448  // (v0 - v1) / (v2 / v3) --> (vovovov) (v0 + v1) * (v3 / v2)
30449  else if ((details::e_sub == o0) && (details::e_div == o1) && (details::e_div == o2))
30450  {
30451  const bool synthesis_result =
30452  synthesize_sf4ext_expression::
30453  template compile<vtype,vtype,vtype,vtype>(expr_gen, "(t-t)*(t/t)", v0, v1, v3, v2, result);
30454 
30455  exprtk_debug(("(v0 - v1) / (v2 / v3) --> (vovovov) (v0 - v1) * (v3 / v2)\n"));
30456 
30457  return (synthesis_result) ? result : error_node();
30458  }
30459  // (v0 * v1) / (v2 / v3) --> (vovovov) ((v0 * v1) * v3) / v2
30460  else if ((details::e_mul == o0) && (details::e_div == o1) && (details::e_div == o2))
30461  {
30462  const bool synthesis_result =
30463  synthesize_sf4ext_expression::
30464  template compile<vtype,vtype,vtype,vtype>(expr_gen, "((t*t)*t)/t", v0, v1, v3, v2, result);
30465 
30466  exprtk_debug(("(v0 * v1) / (v2 / v3) --> (vovovov) ((v0 * v1) * v3) / v2\n"));
30467 
30468  return (synthesis_result) ? result : error_node();
30469  }
30470  }
30471 
30472  const bool synthesis_result =
30473  synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
30474  (expr_gen, id(expr_gen, o0, o1, o2), v0, v1, v2, v3,result);
30475 
30476  if (synthesis_result)
30477  return result;
30478  else if (!expr_gen.valid_operator(o0,f0))
30479  return error_node();
30480  else if (!expr_gen.valid_operator(o1,f1))
30481  return error_node();
30482  else if (!expr_gen.valid_operator(o2,f2))
30483  return error_node();
30484  else
30485  return node_type::allocate(*(expr_gen.node_allocator_), v0, v1, v2, v3, f0, f1, f2);
30486  }
30487 
30488  static inline std::string id(expression_generator<Type>& expr_gen,
30489  const details::operator_type o0,
30490  const details::operator_type o1,
30491  const details::operator_type o2)
30492  {
30493  return (details::build_string() << "(t" << expr_gen.to_str(o0) << "t)" << expr_gen.to_str(o1) << "(t" << expr_gen.to_str(o2) << "t)");
30494  }
30495  };
30496 
30498  {
30499  typedef typename vovovoc_t::type0 node_type;
30500  typedef typename vovovoc_t::sf4_type sf4_type;
30501  typedef typename node_type::T0 T0;
30502  typedef typename node_type::T1 T1;
30503  typedef typename node_type::T2 T2;
30504  typedef typename node_type::T3 T3;
30505 
30507  const details::operator_type& operation,
30508  expression_node_ptr (&branch)[2])
30509  {
30510  // (v0 o0 v1) o1 (v2 o2 c)
30511  const details::vov_base_node<Type>* vov = static_cast<details::vov_base_node<Type>*>(branch[0]);
30512  const details::voc_base_node<Type>* voc = static_cast<details::voc_base_node<Type>*>(branch[1]);
30513  const Type& v0 = vov->v0();
30514  const Type& v1 = vov->v1();
30515  const Type& v2 = voc->v ();
30516  const Type c = voc->c ();
30517  const details::operator_type o0 = vov->operation();
30518  const details::operator_type o1 = operation;
30519  const details::operator_type o2 = voc->operation();
30520 
30521  binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
30522  binary_functor_t f1 = reinterpret_cast<binary_functor_t>(0);
30523  binary_functor_t f2 = reinterpret_cast<binary_functor_t>(0);
30524 
30525  details::free_node(*(expr_gen.node_allocator_),branch[0]);
30526  details::free_node(*(expr_gen.node_allocator_),branch[1]);
30527 
30528  expression_node_ptr result = error_node();
30529 
30531  {
30532  // (v0 / v1) * (v2 / c) --> (vovovoc) (v0 * v2) / (v1 * c)
30533  if ((details::e_div == o0) && (details::e_mul == o1) && (details::e_div == o2))
30534  {
30535  const bool synthesis_result =
30536  synthesize_sf4ext_expression::
30537  template compile<vtype,vtype,vtype,ctype>(expr_gen, "(t*t)/(t*t)", v0, v2, v1, c, result);
30538 
30539  exprtk_debug(("(v0 / v1) * (v2 / c) --> (vovovoc) (v0 * v2) / (v1 * c)\n"));
30540 
30541  return (synthesis_result) ? result : error_node();
30542  }
30543  // (v0 / v1) / (v2 / c) --> (vocovov) (v0 * c) / (v1 * v2)
30544  if ((details::e_div == o0) && (details::e_div == o1) && (details::e_div == o2))
30545  {
30546  const bool synthesis_result =
30547  synthesize_sf4ext_expression::
30548  template compile<vtype,ctype,vtype,vtype>(expr_gen, "(t*t)/(t*t)", v0, c, v1, v2, result);
30549 
30550  exprtk_debug(("(v0 / v1) / (v2 / c) --> (vocovov) (v0 * c) / (v1 * v2)\n"));
30551 
30552  return (synthesis_result) ? result : error_node();
30553  }
30554  }
30555 
30556  const bool synthesis_result =
30557  synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
30558  (expr_gen, id(expr_gen, o0, o1, o2), v0, v1, v2, c, result);
30559 
30560  if (synthesis_result)
30561  return result;
30562  else if (!expr_gen.valid_operator(o0,f0))
30563  return error_node();
30564  else if (!expr_gen.valid_operator(o1,f1))
30565  return error_node();
30566  else if (!expr_gen.valid_operator(o2,f2))
30567  return error_node();
30568  else
30569  return node_type::allocate(*(expr_gen.node_allocator_), v0, v1, v2, c, f0, f1, f2);
30570  }
30571 
30572  static inline std::string id(expression_generator<Type>& expr_gen,
30573  const details::operator_type o0,
30574  const details::operator_type o1,
30575  const details::operator_type o2)
30576  {
30577  return (details::build_string() << "(t" << expr_gen.to_str(o0) << "t)" << expr_gen.to_str(o1) << "(t" << expr_gen.to_str(o2) << "t)");
30578  }
30579  };
30580 
30582  {
30583  typedef typename vovocov_t::type0 node_type;
30584  typedef typename vovocov_t::sf4_type sf4_type;
30585  typedef typename node_type::T0 T0;
30586  typedef typename node_type::T1 T1;
30587  typedef typename node_type::T2 T2;
30588  typedef typename node_type::T3 T3;
30589 
30591  const details::operator_type& operation,
30592  expression_node_ptr (&branch)[2])
30593  {
30594  // (v0 o0 v1) o1 (c o2 v2)
30595  const details::vov_base_node<Type>* vov = static_cast<details::vov_base_node<Type>*>(branch[0]);
30596  const details::cov_base_node<Type>* cov = static_cast<details::cov_base_node<Type>*>(branch[1]);
30597  const Type& v0 = vov->v0();
30598  const Type& v1 = vov->v1();
30599  const Type& v2 = cov->v ();
30600  const Type c = cov->c ();
30601  const details::operator_type o0 = vov->operation();
30602  const details::operator_type o1 = operation;
30603  const details::operator_type o2 = cov->operation();
30604 
30605  binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
30606  binary_functor_t f1 = reinterpret_cast<binary_functor_t>(0);
30607  binary_functor_t f2 = reinterpret_cast<binary_functor_t>(0);
30608 
30609  details::free_node(*(expr_gen.node_allocator_),branch[0]);
30610  details::free_node(*(expr_gen.node_allocator_),branch[1]);
30611 
30612  expression_node_ptr result = error_node();
30613 
30615  {
30616  // (v0 / v1) * (c / v2) --> (vocovov) (v0 * c) / (v1 * v2)
30617  if ((details::e_div == o0) && (details::e_mul == o1) && (details::e_div == o2))
30618  {
30619  const bool synthesis_result =
30620  synthesize_sf4ext_expression::
30621  template compile<vtype,ctype,vtype,vtype>(expr_gen, "(t*t)/(t*t)", v0, c, v1, v2, result);
30622 
30623  exprtk_debug(("(v0 / v1) * (c / v2) --> (vocovov) (v0 * c) / (v1 * v2)\n"));
30624 
30625  return (synthesis_result) ? result : error_node();
30626  }
30627  // (v0 / v1) / (c / v2) --> (vovovoc) (v0 * v2) / (v1 * c)
30628  if ((details::e_div == o0) && (details::e_div == o1) && (details::e_div == o2))
30629  {
30630  const bool synthesis_result =
30631  synthesize_sf4ext_expression::
30632  template compile<vtype,vtype,vtype,ctype>(expr_gen, "(t*t)/(t*t)", v0, v2, v1, c, result);
30633 
30634  exprtk_debug(("(v0 / v1) / (c / v2) --> (vovovoc) (v0 * v2) / (v1 * c)\n"));
30635 
30636  return (synthesis_result) ? result : error_node();
30637  }
30638  }
30639 
30640  const bool synthesis_result =
30641  synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
30642  (expr_gen, id(expr_gen, o0, o1, o2), v0, v1, c, v2, result);
30643 
30644  if (synthesis_result)
30645  return result;
30646  else if (!expr_gen.valid_operator(o0,f0))
30647  return error_node();
30648  else if (!expr_gen.valid_operator(o1,f1))
30649  return error_node();
30650  else if (!expr_gen.valid_operator(o2,f2))
30651  return error_node();
30652  else
30653  return node_type::allocate(*(expr_gen.node_allocator_), v0, v1, c, v2, f0, f1, f2);
30654  }
30655 
30656  static inline std::string id(expression_generator<Type>& expr_gen,
30657  const details::operator_type o0,
30658  const details::operator_type o1,
30659  const details::operator_type o2)
30660  {
30661  return (details::build_string() << "(t" << expr_gen.to_str(o0) << "t)" << expr_gen.to_str(o1) << "(t" << expr_gen.to_str(o2) << "t)");
30662  }
30663  };
30664 
30666  {
30667  typedef typename vocovov_t::type0 node_type;
30668  typedef typename vocovov_t::sf4_type sf4_type;
30669  typedef typename node_type::T0 T0;
30670  typedef typename node_type::T1 T1;
30671  typedef typename node_type::T2 T2;
30672  typedef typename node_type::T3 T3;
30673 
30675  const details::operator_type& operation,
30676  expression_node_ptr (&branch)[2])
30677  {
30678  // (v0 o0 c) o1 (v1 o2 v2)
30679  const details::voc_base_node<Type>* voc = static_cast<details::voc_base_node<Type>*>(branch[0]);
30680  const details::vov_base_node<Type>* vov = static_cast<details::vov_base_node<Type>*>(branch[1]);
30681  const Type c = voc->c ();
30682  const Type& v0 = voc->v ();
30683  const Type& v1 = vov->v0();
30684  const Type& v2 = vov->v1();
30685  const details::operator_type o0 = voc->operation();
30686  const details::operator_type o1 = operation;
30687  const details::operator_type o2 = vov->operation();
30688 
30689  binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
30690  binary_functor_t f1 = reinterpret_cast<binary_functor_t>(0);
30691  binary_functor_t f2 = reinterpret_cast<binary_functor_t>(0);
30692 
30693  details::free_node(*(expr_gen.node_allocator_),branch[0]);
30694  details::free_node(*(expr_gen.node_allocator_),branch[1]);
30695 
30696  expression_node_ptr result = error_node();
30697 
30699  {
30700  // (v0 / c) * (v1 / v2) --> (vovocov) (v0 * v1) / (c * v2)
30701  if ((details::e_div == o0) && (details::e_mul == o1) && (details::e_div == o2))
30702  {
30703  const bool synthesis_result =
30704  synthesize_sf4ext_expression::
30705  template compile<vtype,vtype,ctype,vtype>(expr_gen, "(t*t)/(t*t)", v0, v1, c, v2, result);
30706 
30707  exprtk_debug(("(v0 / c) * (v1 / v2) --> (vovocov) (v0 * v1) / (c * v2)\n"));
30708 
30709  return (synthesis_result) ? result : error_node();
30710  }
30711  // (v0 / c) / (v1 / v2) --> (vovocov) (v0 * v2) / (c * v1)
30712  if ((details::e_div == o0) && (details::e_div == o1) && (details::e_div == o2))
30713  {
30714  const bool synthesis_result =
30715  synthesize_sf4ext_expression::
30716  template compile<vtype,vtype,ctype,vtype>(expr_gen, "(t*t)/(t*t)", v0, v2, c, v1, result);
30717 
30718  exprtk_debug(("(v0 / c) / (v1 / v2) --> (vovocov) (v0 * v2) / (c * v1)\n"));
30719 
30720  return (synthesis_result) ? result : error_node();
30721  }
30722  }
30723 
30724  const bool synthesis_result =
30725  synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
30726  (expr_gen, id(expr_gen, o0, o1, o2), v0, c, v1, v2, result);
30727 
30728  if (synthesis_result)
30729  return result;
30730  else if (!expr_gen.valid_operator(o0,f0))
30731  return error_node();
30732  else if (!expr_gen.valid_operator(o1,f1))
30733  return error_node();
30734  else if (!expr_gen.valid_operator(o2,f2))
30735  return error_node();
30736  else
30737  return node_type::allocate(*(expr_gen.node_allocator_), v0, c, v1, v2, f0, f1, f2);
30738  }
30739 
30740  static inline std::string id(expression_generator<Type>& expr_gen,
30741  const details::operator_type o0,
30742  const details::operator_type o1,
30743  const details::operator_type o2)
30744  {
30745  return (details::build_string() << "(t" << expr_gen.to_str(o0) << "t)" << expr_gen.to_str(o1) << "(t" << expr_gen.to_str(o2) << "t)");
30746  }
30747  };
30748 
30750  {
30751  typedef typename covovov_t::type0 node_type;
30752  typedef typename covovov_t::sf4_type sf4_type;
30753  typedef typename node_type::T0 T0;
30754  typedef typename node_type::T1 T1;
30755  typedef typename node_type::T2 T2;
30756  typedef typename node_type::T3 T3;
30757 
30759  const details::operator_type& operation,
30760  expression_node_ptr (&branch)[2])
30761  {
30762  // (c o0 v0) o1 (v1 o2 v2)
30763  const details::cov_base_node<Type>* cov = static_cast<details::cov_base_node<Type>*>(branch[0]);
30764  const details::vov_base_node<Type>* vov = static_cast<details::vov_base_node<Type>*>(branch[1]);
30765  const Type c = cov->c ();
30766  const Type& v0 = cov->v ();
30767  const Type& v1 = vov->v0();
30768  const Type& v2 = vov->v1();
30769  const details::operator_type o0 = cov->operation();
30770  const details::operator_type o1 = operation;
30771  const details::operator_type o2 = vov->operation();
30772 
30773  binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
30774  binary_functor_t f1 = reinterpret_cast<binary_functor_t>(0);
30775  binary_functor_t f2 = reinterpret_cast<binary_functor_t>(0);
30776 
30777  details::free_node(*(expr_gen.node_allocator_),branch[0]);
30778  details::free_node(*(expr_gen.node_allocator_),branch[1]);
30779 
30780  expression_node_ptr result = error_node();
30781 
30783  {
30784  // (c / v0) * (v1 / v2) --> (covovov) (c * v1) / (v0 * v2)
30785  if ((details::e_div == o0) && (details::e_mul == o1) && (details::e_div == o2))
30786  {
30787  const bool synthesis_result =
30788  synthesize_sf4ext_expression::
30789  template compile<ctype,vtype,vtype,vtype>(expr_gen, "(t*t)/(t*t)", c, v1, v0, v2, result);
30790 
30791  exprtk_debug(("(c / v0) * (v1 / v2) --> (covovov) (c * v1) / (v0 * v2)\n"));
30792 
30793  return (synthesis_result) ? result : error_node();
30794  }
30795  // (c / v0) / (v1 / v2) --> (covovov) (c * v2) / (v0 * v1)
30796  if ((details::e_div == o0) && (details::e_div == o1) && (details::e_div == o2))
30797  {
30798  const bool synthesis_result =
30799  synthesize_sf4ext_expression::
30800  template compile<ctype,vtype,vtype,vtype>(expr_gen, "(t*t)/(t*t)", c, v2, v0, v1, result);
30801 
30802  exprtk_debug(("(c / v0) / (v1 / v2) --> (covovov) (c * v2) / (v0 * v1)\n"));
30803 
30804  return (synthesis_result) ? result : error_node();
30805  }
30806  }
30807 
30808  const bool synthesis_result =
30809  synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
30810  (expr_gen, id(expr_gen, o0, o1, o2), c, v0, v1, v2, result);
30811 
30812  if (synthesis_result)
30813  return result;
30814  else if (!expr_gen.valid_operator(o0,f0))
30815  return error_node();
30816  else if (!expr_gen.valid_operator(o1,f1))
30817  return error_node();
30818  else if (!expr_gen.valid_operator(o2,f2))
30819  return error_node();
30820  else
30821  return node_type::allocate(*(expr_gen.node_allocator_), c, v0, v1, v2, f0, f1, f2);
30822  }
30823 
30824  static inline std::string id(expression_generator<Type>& expr_gen,
30825  const details::operator_type o0,
30826  const details::operator_type o1,
30827  const details::operator_type o2)
30828  {
30829  return (details::build_string() << "(t" << expr_gen.to_str(o0) << "t)" << expr_gen.to_str(o1) << "(t" << expr_gen.to_str(o2) << "t)");
30830  }
30831  };
30832 
30834  {
30835  typedef typename covocov_t::type0 node_type;
30836  typedef typename covocov_t::sf4_type sf4_type;
30837  typedef typename node_type::T0 T0;
30838  typedef typename node_type::T1 T1;
30839  typedef typename node_type::T2 T2;
30840  typedef typename node_type::T3 T3;
30841 
30843  const details::operator_type& operation,
30844  expression_node_ptr (&branch)[2])
30845  {
30846  // (c0 o0 v0) o1 (c1 o2 v1)
30847  const details::cov_base_node<Type>* cov0 = static_cast<details::cov_base_node<Type>*>(branch[0]);
30848  const details::cov_base_node<Type>* cov1 = static_cast<details::cov_base_node<Type>*>(branch[1]);
30849  const Type c0 = cov0->c();
30850  const Type& v0 = cov0->v();
30851  const Type c1 = cov1->c();
30852  const Type& v1 = cov1->v();
30853  const details::operator_type o0 = cov0->operation();
30854  const details::operator_type o1 = operation;
30855  const details::operator_type o2 = cov1->operation();
30856 
30857  binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
30858  binary_functor_t f1 = reinterpret_cast<binary_functor_t>(0);
30859  binary_functor_t f2 = reinterpret_cast<binary_functor_t>(0);
30860 
30861  details::free_node(*(expr_gen.node_allocator_),branch[0]);
30862  details::free_node(*(expr_gen.node_allocator_),branch[1]);
30863 
30864  expression_node_ptr result = error_node();
30865 
30867  {
30868  // (c0 + v0) + (c1 + v1) --> (covov) (c0 + c1) + v0 + v1
30869  if ((details::e_add == o0) && (details::e_add == o1) && (details::e_add == o2))
30870  {
30871  const bool synthesis_result =
30872  synthesize_sf3ext_expression::
30873  template compile<ctype,vtype,vtype>(expr_gen, "(t+t)+t", (c0 + c1), v0, v1, result);
30874 
30875  exprtk_debug(("(c0 + v0) + (c1 + v1) --> (covov) (c0 + c1) + v0 + v1\n"));
30876 
30877  return (synthesis_result) ? result : error_node();
30878  }
30879  // (c0 + v0) - (c1 + v1) --> (covov) (c0 - c1) + v0 - v1
30880  else if ((details::e_add == o0) && (details::e_sub == o1) && (details::e_add == o2))
30881  {
30882  const bool synthesis_result =
30883  synthesize_sf3ext_expression::
30884  template compile<ctype,vtype,vtype>(expr_gen, "(t+t)-t", (c0 - c1), v0, v1, result);
30885 
30886  exprtk_debug(("(c0 + v0) - (c1 + v1) --> (covov) (c0 - c1) + v0 - v1\n"));
30887 
30888  return (synthesis_result) ? result : error_node();
30889  }
30890  // (c0 - v0) - (c1 - v1) --> (covov) (c0 - c1) - v0 + v1
30891  else if ((details::e_sub == o0) && (details::e_sub == o1) && (details::e_sub == o2))
30892  {
30893  const bool synthesis_result =
30894  synthesize_sf3ext_expression::
30895  template compile<ctype,vtype,vtype>(expr_gen, "(t-t)+t", (c0 - c1), v0, v1, result);
30896 
30897  exprtk_debug(("(c0 - v0) - (c1 - v1) --> (covov) (c0 - c1) - v0 + v1\n"));
30898 
30899  return (synthesis_result) ? result : error_node();
30900  }
30901  // (c0 * v0) * (c1 * v1) --> (covov) (c0 * c1) * v0 * v1
30902  else if ((details::e_mul == o0) && (details::e_mul == o1) && (details::e_mul == o2))
30903  {
30904  const bool synthesis_result =
30905  synthesize_sf3ext_expression::
30906  template compile<ctype,vtype,vtype>(expr_gen, "(t*t)*t", (c0 * c1), v0, v1, result);
30907 
30908  exprtk_debug(("(c0 * v0) * (c1 * v1) --> (covov) (c0 * c1) * v0 * v1\n"));
30909 
30910  return (synthesis_result) ? result : error_node();
30911  }
30912  // (c0 * v0) / (c1 * v1) --> (covov) (c0 / c1) * (v0 / v1)
30913  else if ((details::e_mul == o0) && (details::e_div == o1) && (details::e_mul == o2))
30914  {
30915  const bool synthesis_result =
30916  synthesize_sf3ext_expression::
30917  template compile<ctype,vtype,vtype>(expr_gen, "(t*t)/t", (c0 / c1), v0, v1, result);
30918 
30919  exprtk_debug(("(c0 * v0) / (c1 * v1) --> (covov) (c0 / c1) * (v0 / v1)\n"));
30920 
30921  return (synthesis_result) ? result : error_node();
30922  }
30923  // (c0 / v0) * (c1 / v1) --> (covov) (c0 * c1) / (v0 * v1)
30924  else if ((details::e_div == o0) && (details::e_mul == o1) && (details::e_div == o2))
30925  {
30926  const bool synthesis_result =
30927  synthesize_sf3ext_expression::
30928  template compile<ctype,vtype,vtype>(expr_gen, "t/(t*t)", (c0 * c1), v0, v1, result);
30929 
30930  exprtk_debug(("(c0 / v0) * (c1 / v1) --> (covov) (c0 * c1) / (v0 * v1)\n"));
30931 
30932  return (synthesis_result) ? result : error_node();
30933  }
30934  // (c0 / v0) / (c1 / v1) --> (covov) ((c0 / c1) * v1) / v0
30935  else if ((details::e_div == o0) && (details::e_div == o1) && (details::e_div == o2))
30936  {
30937  const bool synthesis_result =
30938  synthesize_sf3ext_expression::
30939  template compile<ctype,vtype,vtype>(expr_gen, "(t*t)/t", (c0 / c1), v1, v0, result);
30940 
30941  exprtk_debug(("(c0 / v0) / (c1 / v1) --> (covov) ((c0 / c1) * v1) / v0\n"));
30942 
30943  return (synthesis_result) ? result : error_node();
30944  }
30945  // (c0 * v0) / (c1 / v1) --> (covov) (c0 / c1) * (v0 * v1)
30946  else if ((details::e_mul == o0) && (details::e_div == o1) && (details::e_div == o2))
30947  {
30948  const bool synthesis_result =
30949  synthesize_sf3ext_expression::
30950  template compile<ctype,vtype,vtype>(expr_gen, "t*(t*t)", (c0 / c1), v0, v1, result);
30951 
30952  exprtk_debug(("(c0 * v0) / (c1 / v1) --> (covov) (c0 / c1) * (v0 * v1)\n"));
30953 
30954  return (synthesis_result) ? result : error_node();
30955  }
30956  // (c0 / v0) / (c1 * v1) --> (covov) (c0 / c1) / (v0 * v1)
30957  else if ((details::e_div == o0) && (details::e_div == o1) && (details::e_mul == o2))
30958  {
30959  const bool synthesis_result =
30960  synthesize_sf3ext_expression::
30961  template compile<ctype,vtype,vtype>(expr_gen, "t/(t*t)", (c0 / c1), v0, v1, result);
30962 
30963  exprtk_debug(("(c0 / v0) / (c1 * v1) --> (covov) (c0 / c1) / (v0 * v1)\n"));
30964 
30965  return (synthesis_result) ? result : error_node();
30966  }
30967  // (c * v0) +/- (c * v1) --> (covov) c * (v0 +/- v1)
30968  else if (
30969  (std::equal_to<T>()(c0,c1)) &&
30970  (details::e_mul == o0) &&
30971  (details::e_mul == o2) &&
30972  (
30973  (details::e_add == o1) ||
30974  (details::e_sub == o1)
30975  )
30976  )
30977  {
30978  std::string specfunc;
30979 
30980  switch (o1)
30981  {
30982  case details::e_add : specfunc = "t*(t+t)"; break;
30983  case details::e_sub : specfunc = "t*(t-t)"; break;
30984  default : return error_node();
30985  }
30986 
30987  const bool synthesis_result =
30988  synthesize_sf3ext_expression::
30989  template compile<ctype, vtype, vtype>(expr_gen, specfunc, c0, v0, v1, result);
30990 
30991  exprtk_debug(("(c * v0) +/- (c * v1) --> (covov) c * (v0 +/- v1)\n"));
30992 
30993  return (synthesis_result) ? result : error_node();
30994  }
30995  }
30996 
30997  const bool synthesis_result =
30998  synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
30999  (expr_gen, id(expr_gen, o0, o1, o2), c0, v0, c1, v1, result);
31000 
31001  if (synthesis_result)
31002  return result;
31003  else if (!expr_gen.valid_operator(o0,f0))
31004  return error_node();
31005  else if (!expr_gen.valid_operator(o1,f1))
31006  return error_node();
31007  else if (!expr_gen.valid_operator(o2,f2))
31008  return error_node();
31009  else
31010  return node_type::allocate(*(expr_gen.node_allocator_), c0, v0, c1, v1, f0, f1, f2);
31011  }
31012 
31013  static inline std::string id(expression_generator<Type>& expr_gen,
31014  const details::operator_type o0,
31015  const details::operator_type o1,
31016  const details::operator_type o2)
31017  {
31018  return (details::build_string() << "(t" << expr_gen.to_str(o0) << "t)" << expr_gen.to_str(o1) << "(t" << expr_gen.to_str(o2) << "t)");
31019  }
31020  };
31021 
31023  {
31024  typedef typename vocovoc_t::type0 node_type;
31025  typedef typename vocovoc_t::sf4_type sf4_type;
31026  typedef typename node_type::T0 T0;
31027  typedef typename node_type::T1 T1;
31028  typedef typename node_type::T2 T2;
31029  typedef typename node_type::T3 T3;
31030 
31032  const details::operator_type& operation,
31033  expression_node_ptr (&branch)[2])
31034  {
31035  // (v0 o0 c0) o1 (v1 o2 c1)
31036  const details::voc_base_node<Type>* voc0 = static_cast<details::voc_base_node<Type>*>(branch[0]);
31037  const details::voc_base_node<Type>* voc1 = static_cast<details::voc_base_node<Type>*>(branch[1]);
31038  const Type c0 = voc0->c();
31039  const Type& v0 = voc0->v();
31040  const Type c1 = voc1->c();
31041  const Type& v1 = voc1->v();
31042  const details::operator_type o0 = voc0->operation();
31043  const details::operator_type o1 = operation;
31044  const details::operator_type o2 = voc1->operation();
31045 
31046  binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
31047  binary_functor_t f1 = reinterpret_cast<binary_functor_t>(0);
31048  binary_functor_t f2 = reinterpret_cast<binary_functor_t>(0);
31049 
31050  details::free_node(*(expr_gen.node_allocator_),branch[0]);
31051  details::free_node(*(expr_gen.node_allocator_),branch[1]);
31052 
31053  expression_node_ptr result = error_node();
31054 
31056  {
31057  // (v0 + c0) + (v1 + c1) --> (covov) (c0 + c1) + v0 + v1
31058  if ((details::e_add == o0) && (details::e_add == o1) && (details::e_add == o2))
31059  {
31060  const bool synthesis_result =
31061  synthesize_sf3ext_expression::
31062  template compile<ctype,vtype,vtype>(expr_gen, "(t+t)+t", (c0 + c1), v0, v1, result);
31063 
31064  exprtk_debug(("(v0 + c0) + (v1 + c1) --> (covov) (c0 + c1) + v0 + v1\n"));
31065 
31066  return (synthesis_result) ? result : error_node();
31067  }
31068  // (v0 + c0) - (v1 + c1) --> (covov) (c0 - c1) + v0 - v1
31069  else if ((details::e_add == o0) && (details::e_sub == o1) && (details::e_add == o2))
31070  {
31071  const bool synthesis_result =
31072  synthesize_sf3ext_expression::
31073  template compile<ctype,vtype,vtype>(expr_gen, "(t+t)-t", (c0 - c1), v0, v1, result);
31074 
31075  exprtk_debug(("(v0 + c0) - (v1 + c1) --> (covov) (c0 - c1) + v0 - v1\n"));
31076 
31077  return (synthesis_result) ? result : error_node();
31078  }
31079  // (v0 - c0) - (v1 - c1) --> (covov) (c1 - c0) + v0 - v1
31080  else if ((details::e_sub == o0) && (details::e_sub == o1) && (details::e_sub == o2))
31081  {
31082  const bool synthesis_result =
31083  synthesize_sf3ext_expression::
31084  template compile<ctype,vtype,vtype>(expr_gen, "(t+t)-t", (c1 - c0), v0, v1, result);
31085 
31086  exprtk_debug(("(v0 - c0) - (v1 - c1) --> (covov) (c1 - c0) + v0 - v1\n"));
31087 
31088  return (synthesis_result) ? result : error_node();
31089  }
31090  // (v0 * c0) * (v1 * c1) --> (covov) (c0 * c1) * v0 * v1
31091  else if ((details::e_mul == o0) && (details::e_mul == o1) && (details::e_mul == o2))
31092  {
31093  const bool synthesis_result =
31094  synthesize_sf3ext_expression::
31095  template compile<ctype,vtype,vtype>(expr_gen, "(t*t)*t", (c0 * c1), v0, v1, result);
31096 
31097  exprtk_debug(("(v0 * c0) * (v1 * c1) --> (covov) (c0 * c1) * v0 * v1\n"));
31098 
31099  return (synthesis_result) ? result : error_node();
31100  }
31101  // (v0 * c0) / (v1 * c1) --> (covov) (c0 / c1) * (v0 / v1)
31102  else if ((details::e_mul == o0) && (details::e_div == o1) && (details::e_mul == o2))
31103  {
31104  const bool synthesis_result =
31105  synthesize_sf3ext_expression::
31106  template compile<ctype,vtype,vtype>(expr_gen, "(t*t)/t", (c0 / c1), v0, v1, result);
31107 
31108  exprtk_debug(("(v0 * c0) / (v1 * c1) --> (covov) (c0 / c1) * (v0 / v1)\n"));
31109 
31110  return (synthesis_result) ? result : error_node();
31111  }
31112  // (v0 / c0) * (v1 / c1) --> (covov) (1 / (c0 * c1)) * v0 * v1
31113  else if ((details::e_div == o0) && (details::e_mul == o1) && (details::e_div == o2))
31114  {
31115  const bool synthesis_result =
31116  synthesize_sf3ext_expression::
31117  template compile<ctype,vtype,vtype>(expr_gen, "(t*t)*t", Type(1) / (c0 * c1), v0, v1, result);
31118 
31119  exprtk_debug(("(v0 / c0) * (v1 / c1) --> (covov) (1 / (c0 * c1)) * v0 * v1\n"));
31120 
31121  return (synthesis_result) ? result : error_node();
31122  }
31123  // (v0 / c0) / (v1 / c1) --> (covov) ((c1 / c0) * v0) / v1
31124  else if ((details::e_div == o0) && (details::e_div == o1) && (details::e_div == o2))
31125  {
31126  const bool synthesis_result =
31127  synthesize_sf3ext_expression::
31128  template compile<ctype,vtype,vtype>(expr_gen, "(t*t)/t", (c1 / c0), v0, v1, result);
31129 
31130  exprtk_debug(("(v0 / c0) / (v1 / c1) --> (covov) ((c1 / c0) * v0) / v1\n"));
31131 
31132  return (synthesis_result) ? result : error_node();
31133  }
31134  // (v0 * c0) / (v1 / c1) --> (covov) (c0 * c1) * (v0 / v1)
31135  else if ((details::e_mul == o0) && (details::e_div == o1) && (details::e_div == o2))
31136  {
31137  const bool synthesis_result =
31138  synthesize_sf3ext_expression::
31139  template compile<ctype,vtype,vtype>(expr_gen, "t*(t/t)", (c0 * c1), v0, v1, result);
31140 
31141  exprtk_debug(("(v0 * c0) / (v1 / c1) --> (covov) (c0 * c1) * (v0 / v1)\n"));
31142 
31143  return (synthesis_result) ? result : error_node();
31144  }
31145  // (v0 / c0) / (v1 * c1) --> (covov) (1 / (c0 * c1)) * v0 / v1
31146  else if ((details::e_div == o0) && (details::e_div == o1) && (details::e_mul == o2))
31147  {
31148  const bool synthesis_result =
31149  synthesize_sf3ext_expression::
31150  template compile<ctype,vtype,vtype>(expr_gen, "t*(t/t)", Type(1) / (c0 * c1), v0, v1, result);
31151 
31152  exprtk_debug(("(v0 / c0) / (v1 * c1) --> (covov) (1 / (c0 * c1)) * v0 / v1\n"));
31153 
31154  return (synthesis_result) ? result : error_node();
31155  }
31156  // (v0 / c0) * (v1 + c1) --> (vocovoc) (v0 * (1 / c0)) * (v1 + c1)
31157  else if ((details::e_div == o0) && (details::e_mul == o1) && (details::e_add == o2))
31158  {
31159  const bool synthesis_result =
31160  synthesize_sf4ext_expression::
31161  template compile<vtype,ctype,vtype,ctype>(expr_gen, "(t*t)*(t+t)", v0, T(1) / c0, v1, c1, result);
31162 
31163  exprtk_debug(("(v0 / c0) * (v1 + c1) --> (vocovoc) (v0 * (1 / c0)) * (v1 + c1)\n"));
31164 
31165  return (synthesis_result) ? result : error_node();
31166  }
31167  // (v0 / c0) * (v1 - c1) --> (vocovoc) (v0 * (1 / c0)) * (v1 - c1)
31168  else if ((details::e_div == o0) && (details::e_mul == o1) && (details::e_sub == o2))
31169  {
31170  const bool synthesis_result =
31171  synthesize_sf4ext_expression::
31172  template compile<vtype,ctype,vtype,ctype>(expr_gen, "(t*t)*(t-t)", v0, T(1) / c0, v1, c1, result);
31173 
31174  exprtk_debug(("(v0 / c0) * (v1 - c1) --> (vocovoc) (v0 * (1 / c0)) * (v1 - c1)\n"));
31175 
31176  return (synthesis_result) ? result : error_node();
31177  }
31178  // (v0 * c) +/- (v1 * c) --> (covov) c * (v0 +/- v1)
31179  else if (
31180  (std::equal_to<T>()(c0,c1)) &&
31181  (details::e_mul == o0) &&
31182  (details::e_mul == o2) &&
31183  (
31184  (details::e_add == o1) ||
31185  (details::e_sub == o1)
31186  )
31187  )
31188  {
31189  std::string specfunc;
31190 
31191  switch (o1)
31192  {
31193  case details::e_add : specfunc = "t*(t+t)"; break;
31194  case details::e_sub : specfunc = "t*(t-t)"; break;
31195  default : return error_node();
31196  }
31197 
31198  const bool synthesis_result =
31199  synthesize_sf3ext_expression::
31200  template compile<ctype,vtype,vtype>(expr_gen, specfunc, c0, v0, v1, result);
31201 
31202  exprtk_debug(("(v0 * c) +/- (v1 * c) --> (covov) c * (v0 +/- v1)\n"));
31203 
31204  return (synthesis_result) ? result : error_node();
31205  }
31206  // (v0 / c) +/- (v1 / c) --> (vovoc) (v0 +/- v1) / c
31207  else if (
31208  (std::equal_to<T>()(c0,c1)) &&
31209  (details::e_div == o0) &&
31210  (details::e_div == o2) &&
31211  (
31212  (details::e_add == o1) ||
31213  (details::e_sub == o1)
31214  )
31215  )
31216  {
31217  std::string specfunc;
31218 
31219  switch (o1)
31220  {
31221  case details::e_add : specfunc = "(t+t)/t"; break;
31222  case details::e_sub : specfunc = "(t-t)/t"; break;
31223  default : return error_node();
31224  }
31225 
31226  const bool synthesis_result =
31227  synthesize_sf3ext_expression::
31228  template compile<vtype,vtype,ctype>(expr_gen, specfunc, v0, v1, c0, result);
31229 
31230  exprtk_debug(("(v0 / c) +/- (v1 / c) --> (vovoc) (v0 +/- v1) / c\n"));
31231 
31232  return (synthesis_result) ? result : error_node();
31233  }
31234  }
31235 
31236  const bool synthesis_result =
31237  synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
31238  (expr_gen, id(expr_gen, o0, o1, o2), v0, c0, v1, c1, result);
31239 
31240  if (synthesis_result)
31241  return result;
31242  else if (!expr_gen.valid_operator(o0,f0))
31243  return error_node();
31244  else if (!expr_gen.valid_operator(o1,f1))
31245  return error_node();
31246  else if (!expr_gen.valid_operator(o2,f2))
31247  return error_node();
31248  else
31249  return node_type::allocate(*(expr_gen.node_allocator_), v0, c0, v1, c1, f0, f1, f2);
31250  }
31251 
31252  static inline std::string id(expression_generator<Type>& expr_gen,
31253  const details::operator_type o0,
31254  const details::operator_type o1,
31255  const details::operator_type o2)
31256  {
31257  return (details::build_string() << "(t" << expr_gen.to_str(o0) << "t)" << expr_gen.to_str(o1) << "(t" << expr_gen.to_str(o2) << "t)");
31258  }
31259  };
31260 
31262  {
31263  typedef typename covovoc_t::type0 node_type;
31264  typedef typename covovoc_t::sf4_type sf4_type;
31265  typedef typename node_type::T0 T0;
31266  typedef typename node_type::T1 T1;
31267  typedef typename node_type::T2 T2;
31268  typedef typename node_type::T3 T3;
31269 
31271  const details::operator_type& operation,
31272  expression_node_ptr (&branch)[2])
31273  {
31274  // (c0 o0 v0) o1 (v1 o2 c1)
31275  const details::cov_base_node<Type>* cov = static_cast<details::cov_base_node<Type>*>(branch[0]);
31276  const details::voc_base_node<Type>* voc = static_cast<details::voc_base_node<Type>*>(branch[1]);
31277  const Type c0 = cov->c();
31278  const Type& v0 = cov->v();
31279  const Type c1 = voc->c();
31280  const Type& v1 = voc->v();
31281  const details::operator_type o0 = cov->operation();
31282  const details::operator_type o1 = operation;
31283  const details::operator_type o2 = voc->operation();
31284 
31285  binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
31286  binary_functor_t f1 = reinterpret_cast<binary_functor_t>(0);
31287  binary_functor_t f2 = reinterpret_cast<binary_functor_t>(0);
31288 
31289  details::free_node(*(expr_gen.node_allocator_),branch[0]);
31290  details::free_node(*(expr_gen.node_allocator_),branch[1]);
31291 
31292  expression_node_ptr result = error_node();
31293 
31295  {
31296  // (c0 + v0) + (v1 + c1) --> (covov) (c0 + c1) + v0 + v1
31297  if ((details::e_add == o0) && (details::e_add == o1) && (details::e_add == o2))
31298  {
31299  const bool synthesis_result =
31300  synthesize_sf3ext_expression::
31301  template compile<ctype,vtype,vtype>(expr_gen, "(t+t)+t", (c0 + c1), v0, v1, result);
31302 
31303  exprtk_debug(("(c0 + v0) + (v1 + c1) --> (covov) (c0 + c1) + v0 + v1\n"));
31304 
31305  return (synthesis_result) ? result : error_node();
31306  }
31307  // (c0 + v0) - (v1 + c1) --> (covov) (c0 - c1) + v0 - v1
31308  else if ((details::e_add == o0) && (details::e_sub == o1) && (details::e_add == o2))
31309  {
31310  const bool synthesis_result =
31311  synthesize_sf3ext_expression::
31312  template compile<ctype,vtype,vtype>(expr_gen, "(t+t)-t", (c0 - c1), v0, v1, result);
31313 
31314  exprtk_debug(("(c0 + v0) - (v1 + c1) --> (covov) (c0 - c1) + v0 - v1\n"));
31315 
31316  return (synthesis_result) ? result : error_node();
31317  }
31318  // (c0 - v0) - (v1 - c1) --> (covov) (c0 + c1) - v0 - v1
31319  else if ((details::e_sub == o0) && (details::e_sub == o1) && (details::e_sub == o2))
31320  {
31321  const bool synthesis_result =
31322  synthesize_sf3ext_expression::
31323  template compile<ctype,vtype,vtype>(expr_gen, "t-(t+t)", (c0 + c1), v0, v1, result);
31324 
31325  exprtk_debug(("(c0 - v0) - (v1 - c1) --> (covov) (c0 + c1) - v0 - v1\n"));
31326 
31327  return (synthesis_result) ? result : error_node();
31328  }
31329  // (c0 * v0) * (v1 * c1) --> (covov) (c0 * c1) * v0 * v1
31330  else if ((details::e_mul == o0) && (details::e_mul == o1) && (details::e_mul == o2))
31331  {
31332  const bool synthesis_result =
31333  synthesize_sf3ext_expression::
31334  template compile<ctype,vtype,vtype>(expr_gen, "(t*t)*t", (c0 * c1), v0, v1, result);
31335 
31336  exprtk_debug(("(c0 * v0) * (v1 * c1) --> (covov) (c0 * c1) * v0 * v1\n"));
31337 
31338  return (synthesis_result) ? result : error_node();
31339  }
31340  // (c0 * v0) / (v1 * c1) --> (covov) (c0 / c1) * (v0 / v1)
31341  else if ((details::e_mul == o0) && (details::e_div == o1) && (details::e_mul == o2))
31342  {
31343  const bool synthesis_result =
31344  synthesize_sf3ext_expression::
31345  template compile<ctype,vtype,vtype>(expr_gen, "(t*t)/t", (c0 / c1), v0, v1, result);
31346 
31347  exprtk_debug(("(c0 * v0) / (v1 * c1) --> (covov) (c0 / c1) * (v0 / v1)\n"));
31348 
31349  return (synthesis_result) ? result : error_node();
31350  }
31351  // (c0 / v0) * (v1 / c1) --> (covov) (c0 / c1) * (v1 / v0)
31352  else if ((details::e_div == o0) && (details::e_mul == o1) && (details::e_div == o2))
31353  {
31354  const bool synthesis_result =
31355  synthesize_sf3ext_expression::
31356  template compile<ctype,vtype,vtype>(expr_gen, "t*(t/t)", (c0 / c1), v1, v0, result);
31357 
31358  exprtk_debug(("(c0 / v0) * (v1 / c1) --> (covov) (c0 / c1) * (v1 / v0)\n"));
31359 
31360  return (synthesis_result) ? result : error_node();
31361  }
31362  // (c0 / v0) / (v1 / c1) --> (covov) (c0 * c1) / (v0 * v1)
31363  else if ((details::e_div == o0) && (details::e_div == o1) && (details::e_div == o2))
31364  {
31365  const bool synthesis_result =
31366  synthesize_sf3ext_expression::
31367  template compile<ctype,vtype,vtype>(expr_gen, "t/(t*t)", (c0 * c1), v0, v1, result);
31368 
31369  exprtk_debug(("(c0 / v0) / (v1 / c1) --> (covov) (c0 * c1) / (v0 * v1)\n"));
31370 
31371  return (synthesis_result) ? result : error_node();
31372  }
31373  // (c0 * v0) / (v1 / c1) --> (covov) (c0 * c1) * (v0 / v1)
31374  else if ((details::e_mul == o0) && (details::e_div == o1) && (details::e_div == o2))
31375  {
31376  const bool synthesis_result =
31377  synthesize_sf3ext_expression::
31378  template compile<ctype,vtype,vtype>(expr_gen, "(t*t)/t", (c0 * c1), v0, v1, result);
31379 
31380  exprtk_debug(("(c0 * v0) / (v1 / c1) --> (covov) (c0 * c1) * (v0 / v1)\n"));
31381 
31382  return (synthesis_result) ? result : error_node();
31383  }
31384  // (c0 / v0) / (v1 * c1) --> (covov) (c0 / c1) / (v0 * v1)
31385  else if ((details::e_div == o0) && (details::e_div == o1) && (details::e_mul == o2))
31386  {
31387  const bool synthesis_result =
31388  synthesize_sf3ext_expression::
31389  template compile<ctype,vtype,vtype>(expr_gen, "t/(t*t)", (c0 / c1), v0, v1, result);
31390 
31391  exprtk_debug(("(c0 / v0) / (v1 * c1) --> (covov) (c0 / c1) / (v0 * v1)\n"));
31392 
31393  return (synthesis_result) ? result : error_node();
31394  }
31395  // (c * v0) +/- (v1 * c) --> (covov) c * (v0 +/- v1)
31396  else if (
31397  (std::equal_to<T>()(c0,c1)) &&
31398  (details::e_mul == o0) &&
31399  (details::e_mul == o2) &&
31400  (
31401  (details::e_add == o1) ||
31402  (details::e_sub == o1)
31403  )
31404  )
31405  {
31406  std::string specfunc;
31407 
31408  switch (o1)
31409  {
31410  case details::e_add : specfunc = "t*(t+t)"; break;
31411  case details::e_sub : specfunc = "t*(t-t)"; break;
31412  default : return error_node();
31413  }
31414 
31415  const bool synthesis_result =
31416  synthesize_sf3ext_expression::
31417  template compile<ctype,vtype,vtype>(expr_gen,specfunc, c0, v0, v1, result);
31418 
31419  exprtk_debug(("(c * v0) +/- (v1 * c) --> (covov) c * (v0 +/- v1)\n"));
31420 
31421  return (synthesis_result) ? result : error_node();
31422  }
31423  }
31424 
31425  const bool synthesis_result =
31426  synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
31427  (expr_gen, id(expr_gen, o0, o1, o2), c0, v0, v1, c1, result);
31428 
31429  if (synthesis_result)
31430  return result;
31431  else if (!expr_gen.valid_operator(o0,f0))
31432  return error_node();
31433  else if (!expr_gen.valid_operator(o1,f1))
31434  return error_node();
31435  else if (!expr_gen.valid_operator(o2,f2))
31436  return error_node();
31437  else
31438  return node_type::allocate(*(expr_gen.node_allocator_), c0, v0, v1, c1, f0, f1, f2);
31439  }
31440 
31441  static inline std::string id(expression_generator<Type>& expr_gen,
31442  const details::operator_type o0,
31443  const details::operator_type o1,
31444  const details::operator_type o2)
31445  {
31446  return (details::build_string() << "(t" << expr_gen.to_str(o0) << "t)" << expr_gen.to_str(o1) << "(t" << expr_gen.to_str(o2) << "t)");
31447  }
31448  };
31449 
31451  {
31452  typedef typename vococov_t::type0 node_type;
31453  typedef typename vococov_t::sf4_type sf4_type;
31454  typedef typename node_type::T0 T0;
31455  typedef typename node_type::T1 T1;
31456  typedef typename node_type::T2 T2;
31457  typedef typename node_type::T3 T3;
31458 
31460  const details::operator_type& operation,
31461  expression_node_ptr (&branch)[2])
31462  {
31463  // (v0 o0 c0) o1 (c1 o2 v1)
31464  const details::voc_base_node<Type>* voc = static_cast<details::voc_base_node<Type>*>(branch[0]);
31465  const details::cov_base_node<Type>* cov = static_cast<details::cov_base_node<Type>*>(branch[1]);
31466  const Type c0 = voc->c();
31467  const Type& v0 = voc->v();
31468  const Type c1 = cov->c();
31469  const Type& v1 = cov->v();
31470  const details::operator_type o0 = voc->operation();
31471  const details::operator_type o1 = operation;
31472  const details::operator_type o2 = cov->operation();
31473 
31474  binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
31475  binary_functor_t f1 = reinterpret_cast<binary_functor_t>(0);
31476  binary_functor_t f2 = reinterpret_cast<binary_functor_t>(0);
31477 
31478  details::free_node(*(expr_gen.node_allocator_),branch[0]);
31479  details::free_node(*(expr_gen.node_allocator_),branch[1]);
31480 
31481  expression_node_ptr result = error_node();
31482 
31484  {
31485  // (v0 + c0) + (c1 + v1) --> (covov) (c0 + c1) + v0 + v1
31486  if ((details::e_add == o0) && (details::e_add == o1) && (details::e_add == o2))
31487  {
31488  const bool synthesis_result =
31489  synthesize_sf3ext_expression::
31490  template compile<ctype,vtype,vtype>(expr_gen, "(t+t)+t", (c0 + c1), v0, v1, result);
31491 
31492  exprtk_debug(("(v0 + c0) + (c1 + v1) --> (covov) (c0 + c1) + v0 + v1\n"));
31493 
31494  return (synthesis_result) ? result : error_node();
31495  }
31496  // (v0 + c0) - (c1 + v1) --> (covov) (c0 - c1) + v0 - v1
31497  else if ((details::e_add == o0) && (details::e_sub == o1) && (details::e_add == o2))
31498  {
31499  const bool synthesis_result =
31500  synthesize_sf3ext_expression::
31501  template compile<ctype,vtype,vtype>(expr_gen, "(t+t)-t", (c0 - c1), v0, v1, result);
31502 
31503  exprtk_debug(("(v0 + c0) - (c1 + v1) --> (covov) (c0 - c1) + v0 - v1\n"));
31504 
31505  return (synthesis_result) ? result : error_node();
31506  }
31507  // (v0 - c0) - (c1 - v1) --> (vovoc) v0 + v1 - (c1 + c0)
31508  else if ((details::e_sub == o0) && (details::e_sub == o1) && (details::e_sub == o2))
31509  {
31510  const bool synthesis_result =
31511  synthesize_sf3ext_expression::
31512  template compile<vtype,vtype,ctype>(expr_gen, "(t+t)-t", v0, v1, (c1 + c0), result);
31513 
31514  exprtk_debug(("(v0 - c0) - (c1 - v1) --> (vovoc) v0 + v1 - (c1 + c0)\n"));
31515 
31516  return (synthesis_result) ? result : error_node();
31517  }
31518  // (v0 * c0) * (c1 * v1) --> (covov) (c0 * c1) * v0 * v1
31519  else if ((details::e_mul == o0) && (details::e_mul == o1) && (details::e_mul == o2))
31520  {
31521  const bool synthesis_result =
31522  synthesize_sf3ext_expression::
31523  template compile<ctype,vtype,vtype>(expr_gen, "(t*t)*t", (c0 * c1), v0, v1, result);
31524 
31525  exprtk_debug(("(v0 * c0) * (c1 * v1) --> (covov) (c0 * c1) * v0 * v1\n"));
31526 
31527  return (synthesis_result) ? result : error_node();
31528  }
31529  // (v0 * c0) / (c1 * v1) --> (covov) (c0 / c1) * (v0 * v1)
31530  else if ((details::e_mul == o0) && (details::e_div == o1) && (details::e_mul == o2))
31531  {
31532  const bool synthesis_result =
31533  synthesize_sf3ext_expression::
31534  template compile<ctype,vtype,vtype>(expr_gen, "(t*t)/t", (c0 / c1), v0, v1, result);
31535 
31536  exprtk_debug(("(v0 * c0) / (c1 * v1) --> (covov) (c0 / c1) * (v0 * v1)\n"));
31537 
31538  return (synthesis_result) ? result : error_node();
31539  }
31540  // (v0 / c0) * (c1 / v1) --> (covov) (c1 / c0) * (v0 / v1)
31541  else if ((details::e_div == o0) && (details::e_mul == o1) && (details::e_div == o2))
31542  {
31543  const bool synthesis_result =
31544  synthesize_sf3ext_expression::
31545  template compile<ctype,vtype,vtype>(expr_gen, "(t*t)/t", (c1 / c0), v0, v1, result);
31546 
31547  exprtk_debug(("(v0 / c0) * (c1 / v1) --> (covov) (c1 / c0) * (v0 / v1)\n"));
31548 
31549  return (synthesis_result) ? result : error_node();
31550  }
31551  // (v0 * c0) / (c1 / v1) --> (covov) (c0 / c1) * (v0 * v1)
31552  else if ((details::e_mul == o0) && (details::e_div == o1) && (details::e_div == o2))
31553  {
31554  const bool synthesis_result =
31555  synthesize_sf3ext_expression::
31556  template compile<ctype,vtype,vtype>(expr_gen, "(t*t)*t", (c0 / c1), v0, v1, result);
31557 
31558  exprtk_debug(("(v0 * c0) / (c1 / v1) --> (covov) (c0 / c1) * (v0 * v1)\n"));
31559 
31560  return (synthesis_result) ? result : error_node();
31561  }
31562  // (v0 / c0) / (c1 * v1) --> (covov) (1 / (c0 * c1)) * (v0 / v1)
31563  else if ((details::e_div == o0) && (details::e_div == o1) && (details::e_mul == o2))
31564  {
31565  const bool synthesis_result =
31566  synthesize_sf3ext_expression::
31567  template compile<ctype,vtype,vtype>(expr_gen, "(t*t)/t", Type(1) / (c0 * c1), v0, v1, result);
31568 
31569  exprtk_debug(("(v0 / c0) / (c1 * v1) --> (covov) (1 / (c0 * c1)) * (v0 / v1)\n"));
31570 
31571  return (synthesis_result) ? result : error_node();
31572  }
31573  // (v0 / c0) / (c1 / v1) --> (vovoc) (v0 * v1) * (1 / (c0 * c1))
31574  else if ((details::e_div == o0) && (details::e_div == o1) && (details::e_div == o2))
31575  {
31576  const bool synthesis_result =
31577  synthesize_sf3ext_expression::
31578  template compile<vtype,vtype,ctype>(expr_gen, "(t*t)*t", v0, v1, Type(1) / (c0 * c1), result);
31579 
31580  exprtk_debug(("(v0 / c0) / (c1 / v1) --> (vovoc) (v0 * v1) * (1 / (c0 * c1))\n"));
31581 
31582  return (synthesis_result) ? result : error_node();
31583  }
31584  // (v0 * c) +/- (c * v1) --> (covov) c * (v0 +/- v1)
31585  else if (
31586  (std::equal_to<T>()(c0,c1)) &&
31587  (details::e_mul == o0) &&
31588  (details::e_mul == o2) &&
31589  (
31590  (details::e_add == o1) || (details::e_sub == o1)
31591  )
31592  )
31593  {
31594  std::string specfunc;
31595 
31596  switch (o1)
31597  {
31598  case details::e_add : specfunc = "t*(t+t)"; break;
31599  case details::e_sub : specfunc = "t*(t-t)"; break;
31600  default : return error_node();
31601  }
31602 
31603  const bool synthesis_result =
31604  synthesize_sf3ext_expression::
31605  template compile<ctype,vtype,vtype>(expr_gen, specfunc, c0, v0, v1, result);
31606 
31607  exprtk_debug(("(v0 * c) +/- (c * v1) --> (covov) c * (v0 +/- v1)\n"));
31608 
31609  return (synthesis_result) ? result : error_node();
31610  }
31611  }
31612 
31613  const bool synthesis_result =
31614  synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
31615  (expr_gen, id(expr_gen, o0, o1, o2), v0, c0, c1, v1, result);
31616 
31617  if (synthesis_result)
31618  return result;
31619  else if (!expr_gen.valid_operator(o0,f0))
31620  return error_node();
31621  else if (!expr_gen.valid_operator(o1,f1))
31622  return error_node();
31623  else if (!expr_gen.valid_operator(o2,f2))
31624  return error_node();
31625  else
31626  return node_type::allocate(*(expr_gen.node_allocator_), v0, c0, c1, v1, f0, f1, f2);
31627  }
31628 
31629  static inline std::string id(expression_generator<Type>& expr_gen,
31630  const details::operator_type o0,
31631  const details::operator_type o1,
31632  const details::operator_type o2)
31633  {
31634  return (details::build_string() << "(t" << expr_gen.to_str(o0) << "t)" << expr_gen.to_str(o1) << "(t" << expr_gen.to_str(o2) << "t)");
31635  }
31636  };
31637 
31639  {
31640  typedef typename vovovov_t::type1 node_type;
31641  typedef typename vovovov_t::sf4_type sf4_type;
31642  typedef typename node_type::T0 T0;
31643  typedef typename node_type::T1 T1;
31644  typedef typename node_type::T2 T2;
31645  typedef typename node_type::T3 T3;
31646 
31648  const details::operator_type& operation,
31649  expression_node_ptr (&branch)[2])
31650  {
31651  // v0 o0 (v1 o1 (v2 o2 v3))
31652  typedef typename synthesize_vovov_expression1::node_type lcl_vovov_t;
31653 
31654  const lcl_vovov_t* vovov = static_cast<const lcl_vovov_t*>(branch[1]);
31655  const Type& v0 = static_cast<details::variable_node<Type>*>(branch[0])->ref();
31656  const Type& v1 = vovov->t0();
31657  const Type& v2 = vovov->t1();
31658  const Type& v3 = vovov->t2();
31659  const details::operator_type o0 = operation;
31660  const details::operator_type o1 = expr_gen.get_operator(vovov->f0());
31661  const details::operator_type o2 = expr_gen.get_operator(vovov->f1());
31662 
31663  binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
31664  binary_functor_t f1 = vovov->f0();
31665  binary_functor_t f2 = vovov->f1();
31666 
31667  details::free_node(*(expr_gen.node_allocator_),branch[1]);
31668 
31669  expression_node_ptr result = error_node();
31670 
31671  if (synthesize_sf4ext_expression::template compile<T0,T1,T2,T3>(expr_gen,id(expr_gen,o0,o1,o2),v0,v1,v2,v3,result))
31672  return result;
31673  else if (!expr_gen.valid_operator(o0,f0))
31674  return error_node();
31675 
31676  exprtk_debug(("v0 o0 (v1 o1 (v2 o2 v3))\n"));
31677 
31678  return node_type::allocate(*(expr_gen.node_allocator_),v0,v1,v2,v3,f0,f1,f2);
31679  }
31680 
31681  static inline std::string id(expression_generator<Type>& expr_gen,
31682  const details::operator_type o0,
31683  const details::operator_type o1,
31684  const details::operator_type o2)
31685  {
31686  return (details::build_string() << "t" << expr_gen.to_str(o0) << "(t" << expr_gen.to_str(o1) << "(t" << expr_gen.to_str(o2) << "t))");
31687  }
31688  };
31689 
31691  {
31692  typedef typename vovovoc_t::type1 node_type;
31693  typedef typename vovovoc_t::sf4_type sf4_type;
31694  typedef typename node_type::T0 T0;
31695  typedef typename node_type::T1 T1;
31696  typedef typename node_type::T2 T2;
31697  typedef typename node_type::T3 T3;
31698 
31700  const details::operator_type& operation,
31701  expression_node_ptr (&branch)[2])
31702  {
31703  // v0 o0 (v1 o1 (v2 o2 c))
31704  typedef typename synthesize_vovoc_expression1::node_type lcl_vovoc_t;
31705 
31706  const lcl_vovoc_t* vovoc = static_cast<const lcl_vovoc_t*>(branch[1]);
31707  const Type& v0 = static_cast<details::variable_node<Type>*>(branch[0])->ref();
31708  const Type& v1 = vovoc->t0();
31709  const Type& v2 = vovoc->t1();
31710  const Type c = vovoc->t2();
31711  const details::operator_type o0 = operation;
31712  const details::operator_type o1 = expr_gen.get_operator(vovoc->f0());
31713  const details::operator_type o2 = expr_gen.get_operator(vovoc->f1());
31714 
31715  binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
31716  binary_functor_t f1 = vovoc->f0();
31717  binary_functor_t f2 = vovoc->f1();
31718 
31719  details::free_node(*(expr_gen.node_allocator_),branch[1]);
31720 
31721  expression_node_ptr result = error_node();
31722 
31723  const bool synthesis_result =
31724  synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
31725  (expr_gen, id(expr_gen, o0, o1, o2), v0, v1, v2, c, result);
31726 
31727  if (synthesis_result)
31728  return result;
31729  else if (!expr_gen.valid_operator(o0,f0))
31730  return error_node();
31731 
31732  exprtk_debug(("v0 o0 (v1 o1 (v2 o2 c))\n"));
31733 
31734  return node_type::allocate(*(expr_gen.node_allocator_), v0, v1, v2, c, f0, f1, f2);
31735  }
31736 
31737  static inline std::string id(expression_generator<Type>& expr_gen,
31738  const details::operator_type o0,
31739  const details::operator_type o1,
31740  const details::operator_type o2)
31741  {
31742  return (details::build_string() << "t" << expr_gen.to_str(o0) << "(t" << expr_gen.to_str(o1) << "(t" << expr_gen.to_str(o2) << "t))");
31743  }
31744  };
31745 
31747  {
31748  typedef typename vovocov_t::type1 node_type;
31749  typedef typename vovocov_t::sf4_type sf4_type;
31750  typedef typename node_type::T0 T0;
31751  typedef typename node_type::T1 T1;
31752  typedef typename node_type::T2 T2;
31753  typedef typename node_type::T3 T3;
31754 
31756  const details::operator_type& operation,
31757  expression_node_ptr (&branch)[2])
31758  {
31759  // v0 o0 (v1 o1 (c o2 v2))
31760  typedef typename synthesize_vocov_expression1::node_type lcl_vocov_t;
31761 
31762  const lcl_vocov_t* vocov = static_cast<const lcl_vocov_t*>(branch[1]);
31763  const Type& v0 = static_cast<details::variable_node<Type>*>(branch[0])->ref();
31764  const Type& v1 = vocov->t0();
31765  const Type c = vocov->t1();
31766  const Type& v2 = vocov->t2();
31767  const details::operator_type o0 = operation;
31768  const details::operator_type o1 = expr_gen.get_operator(vocov->f0());
31769  const details::operator_type o2 = expr_gen.get_operator(vocov->f1());
31770 
31771  binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
31772  binary_functor_t f1 = vocov->f0();
31773  binary_functor_t f2 = vocov->f1();
31774 
31775  details::free_node(*(expr_gen.node_allocator_),branch[1]);
31776 
31777  expression_node_ptr result = error_node();
31778 
31779  const bool synthesis_result =
31780  synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
31781  (expr_gen, id(expr_gen, o0, o1, o2), v0, v1, c, v2, result);
31782 
31783  if (synthesis_result)
31784  return result;
31785  if (!expr_gen.valid_operator(o0,f0))
31786  return error_node();
31787 
31788  exprtk_debug(("v0 o0 (v1 o1 (c o2 v2))\n"));
31789 
31790  return node_type::allocate(*(expr_gen.node_allocator_), v0, v1, c, v2, f0, f1, f2);
31791  }
31792 
31793  static inline std::string id(expression_generator<Type>& expr_gen,
31794  const details::operator_type o0,
31795  const details::operator_type o1,
31796  const details::operator_type o2)
31797  {
31798  return (details::build_string() << "t" << expr_gen.to_str(o0) << "(t" << expr_gen.to_str(o1) << "(t" << expr_gen.to_str(o2) << "t))");
31799  }
31800  };
31801 
31803  {
31804  typedef typename vocovov_t::type1 node_type;
31805  typedef typename vocovov_t::sf4_type sf4_type;
31806  typedef typename node_type::T0 T0;
31807  typedef typename node_type::T1 T1;
31808  typedef typename node_type::T2 T2;
31809  typedef typename node_type::T3 T3;
31810 
31812  const details::operator_type& operation,
31813  expression_node_ptr (&branch)[2])
31814  {
31815  // v0 o0 (c o1 (v1 o2 v2))
31816  typedef typename synthesize_covov_expression1::node_type lcl_covov_t;
31817 
31818  const lcl_covov_t* covov = static_cast<const lcl_covov_t*>(branch[1]);
31819  const Type& v0 = static_cast<details::variable_node<Type>*>(branch[0])->ref();
31820  const Type c = covov->t0();
31821  const Type& v1 = covov->t1();
31822  const Type& v2 = covov->t2();
31823  const details::operator_type o0 = operation;
31824  const details::operator_type o1 = expr_gen.get_operator(covov->f0());
31825  const details::operator_type o2 = expr_gen.get_operator(covov->f1());
31826 
31827  binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
31828  binary_functor_t f1 = covov->f0();
31829  binary_functor_t f2 = covov->f1();
31830 
31831  details::free_node(*(expr_gen.node_allocator_),branch[1]);
31832 
31833  expression_node_ptr result = error_node();
31834 
31835  const bool synthesis_result =
31836  synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
31837  (expr_gen, id(expr_gen, o0, o1, o2), v0, c, v1, v2, result);
31838 
31839  if (synthesis_result)
31840  return result;
31841  else if (!expr_gen.valid_operator(o0,f0))
31842  return error_node();
31843 
31844  exprtk_debug(("v0 o0 (c o1 (v1 o2 v2))\n"));
31845 
31846  return node_type::allocate(*(expr_gen.node_allocator_), v0, c, v1, v2, f0, f1, f2);
31847  }
31848 
31849  static inline std::string id(expression_generator<Type>& expr_gen,
31850  const details::operator_type o0,
31851  const details::operator_type o1,
31852  const details::operator_type o2)
31853  {
31854  return (details::build_string() << "t" << expr_gen.to_str(o0) << "(t" << expr_gen.to_str(o1) << "(t" << expr_gen.to_str(o2) << "t))");
31855  }
31856  };
31857 
31859  {
31860  typedef typename covovov_t::type1 node_type;
31861  typedef typename covovov_t::sf4_type sf4_type;
31862  typedef typename node_type::T0 T0;
31863  typedef typename node_type::T1 T1;
31864  typedef typename node_type::T2 T2;
31865  typedef typename node_type::T3 T3;
31866 
31868  const details::operator_type& operation,
31869  expression_node_ptr (&branch)[2])
31870  {
31871  // c o0 (v0 o1 (v1 o2 v2))
31872  typedef typename synthesize_vovov_expression1::node_type lcl_vovov_t;
31873 
31874  const lcl_vovov_t* vovov = static_cast<const lcl_vovov_t*>(branch[1]);
31875  const Type c = static_cast<details::literal_node<Type>*>(branch[0])->value();
31876  const Type& v0 = vovov->t0();
31877  const Type& v1 = vovov->t1();
31878  const Type& v2 = vovov->t2();
31879  const details::operator_type o0 = operation;
31880  const details::operator_type o1 = expr_gen.get_operator(vovov->f0());
31881  const details::operator_type o2 = expr_gen.get_operator(vovov->f1());
31882 
31883  binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
31884  binary_functor_t f1 = vovov->f0();
31885  binary_functor_t f2 = vovov->f1();
31886 
31887  details::free_node(*(expr_gen.node_allocator_),branch[0]);
31888  details::free_node(*(expr_gen.node_allocator_),branch[1]);
31889 
31890  expression_node_ptr result = error_node();
31891 
31892  const bool synthesis_result =
31893  synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
31894  (expr_gen, id(expr_gen, o0, o1, o2), c, v0, v1, v2, result);
31895 
31896  if (synthesis_result)
31897  return result;
31898  if (!expr_gen.valid_operator(o0,f0))
31899  return error_node();
31900 
31901  exprtk_debug(("c o0 (v0 o1 (v1 o2 v2))\n"));
31902 
31903  return node_type::allocate(*(expr_gen.node_allocator_), c, v0, v1, v2, f0, f1, f2);
31904  }
31905 
31906  static inline std::string id(expression_generator<Type>& expr_gen,
31907  const details::operator_type o0,
31908  const details::operator_type o1,
31909  const details::operator_type o2)
31910  {
31911  return (details::build_string() << "t" << expr_gen.to_str(o0) << "(t" << expr_gen.to_str(o1) << "(t" << expr_gen.to_str(o2) << "t))");
31912  }
31913  };
31914 
31916  {
31917  typedef typename covocov_t::type1 node_type;
31918  typedef typename covocov_t::sf4_type sf4_type;
31919  typedef typename node_type::T0 T0;
31920  typedef typename node_type::T1 T1;
31921  typedef typename node_type::T2 T2;
31922  typedef typename node_type::T3 T3;
31923 
31925  const details::operator_type& operation,
31926  expression_node_ptr (&branch)[2])
31927  {
31928  // c0 o0 (v0 o1 (c1 o2 v1))
31929  typedef typename synthesize_vocov_expression1::node_type lcl_vocov_t;
31930 
31931  const lcl_vocov_t* vocov = static_cast<const lcl_vocov_t*>(branch[1]);
31932  const Type c0 = static_cast<details::literal_node<Type>*>(branch[0])->value();
31933  const Type& v0 = vocov->t0();
31934  const Type c1 = vocov->t1();
31935  const Type& v1 = vocov->t2();
31936  const details::operator_type o0 = operation;
31937  const details::operator_type o1 = expr_gen.get_operator(vocov->f0());
31938  const details::operator_type o2 = expr_gen.get_operator(vocov->f1());
31939 
31940  binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
31941  binary_functor_t f1 = vocov->f0();
31942  binary_functor_t f2 = vocov->f1();
31943 
31944  details::free_node(*(expr_gen.node_allocator_),branch[0]);
31945  details::free_node(*(expr_gen.node_allocator_),branch[1]);
31946 
31947  expression_node_ptr result = error_node();
31948 
31949  const bool synthesis_result =
31950  synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
31951  (expr_gen, id(expr_gen, o0, o1, o2), c0, v0, c1, v1, result);
31952 
31953  if (synthesis_result)
31954  return result;
31955  else if (!expr_gen.valid_operator(o0,f0))
31956  return error_node();
31957 
31958  exprtk_debug(("c0 o0 (v0 o1 (c1 o2 v1))\n"));
31959 
31960  return node_type::allocate(*(expr_gen.node_allocator_), c0, v0, c1, v1, f0, f1, f2);
31961  }
31962 
31963  static inline std::string id(expression_generator<Type>& expr_gen,
31964  const details::operator_type o0,
31965  const details::operator_type o1,
31966  const details::operator_type o2)
31967  {
31968  return (details::build_string() << "t" << expr_gen.to_str(o0) << "(t" << expr_gen.to_str(o1) << "(t" << expr_gen.to_str(o2) << "t))");
31969  }
31970  };
31971 
31973  {
31974  typedef typename vocovoc_t::type1 node_type;
31975  typedef typename vocovoc_t::sf4_type sf4_type;
31976  typedef typename node_type::T0 T0;
31977  typedef typename node_type::T1 T1;
31978  typedef typename node_type::T2 T2;
31979  typedef typename node_type::T3 T3;
31980 
31982  const details::operator_type& operation,
31983  expression_node_ptr (&branch)[2])
31984  {
31985  // v0 o0 (c0 o1 (v1 o2 c2))
31986  typedef typename synthesize_covoc_expression1::node_type lcl_covoc_t;
31987 
31988  const lcl_covoc_t* covoc = static_cast<const lcl_covoc_t*>(branch[1]);
31989  const Type& v0 = static_cast<details::variable_node<Type>*>(branch[0])->ref();
31990  const Type c0 = covoc->t0();
31991  const Type& v1 = covoc->t1();
31992  const Type c1 = covoc->t2();
31993  const details::operator_type o0 = operation;
31994  const details::operator_type o1 = expr_gen.get_operator(covoc->f0());
31995  const details::operator_type o2 = expr_gen.get_operator(covoc->f1());
31996 
31997  binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
31998  binary_functor_t f1 = covoc->f0();
31999  binary_functor_t f2 = covoc->f1();
32000 
32001  details::free_node(*(expr_gen.node_allocator_),branch[1]);
32002 
32003  expression_node_ptr result = error_node();
32004 
32005  const bool synthesis_result =
32006  synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
32007  (expr_gen, id(expr_gen, o0, o1, o2), v0, c0, v1, c1, result);
32008 
32009  if (synthesis_result)
32010  return result;
32011  else if (!expr_gen.valid_operator(o0,f0))
32012  return error_node();
32013 
32014  exprtk_debug(("v0 o0 (c0 o1 (v1 o2 c2))\n"));
32015 
32016  return node_type::allocate(*(expr_gen.node_allocator_), v0, c0, v1, c1, f0, f1, f2);
32017  }
32018 
32019  static inline std::string id(expression_generator<Type>& expr_gen,
32020  const details::operator_type o0,
32021  const details::operator_type o1,
32022  const details::operator_type o2)
32023  {
32024  return (details::build_string() << "t" << expr_gen.to_str(o0) << "(t" << expr_gen.to_str(o1) << "(t" << expr_gen.to_str(o2) << "t))");
32025  }
32026  };
32027 
32029  {
32030  typedef typename covovoc_t::type1 node_type;
32031  typedef typename covovoc_t::sf4_type sf4_type;
32032  typedef typename node_type::T0 T0;
32033  typedef typename node_type::T1 T1;
32034  typedef typename node_type::T2 T2;
32035  typedef typename node_type::T3 T3;
32037  const details::operator_type& operation,
32038  expression_node_ptr (&branch)[2])
32039  {
32040  // c0 o0 (v0 o1 (v1 o2 c1))
32041  typedef typename synthesize_vovoc_expression1::node_type lcl_vovoc_t;
32042 
32043  const lcl_vovoc_t* vovoc = static_cast<const lcl_vovoc_t*>(branch[1]);
32044  const Type c0 = static_cast<details::literal_node<Type>*>(branch[0])->value();
32045  const Type& v0 = vovoc->t0();
32046  const Type& v1 = vovoc->t1();
32047  const Type c1 = vovoc->t2();
32048  const details::operator_type o0 = operation;
32049  const details::operator_type o1 = expr_gen.get_operator(vovoc->f0());
32050  const details::operator_type o2 = expr_gen.get_operator(vovoc->f1());
32051 
32052  binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
32053  binary_functor_t f1 = vovoc->f0();
32054  binary_functor_t f2 = vovoc->f1();
32055 
32056  details::free_node(*(expr_gen.node_allocator_),branch[0]);
32057  details::free_node(*(expr_gen.node_allocator_),branch[1]);
32058 
32059  expression_node_ptr result = error_node();
32060 
32061  const bool synthesis_result =
32062  synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
32063  (expr_gen, id(expr_gen, o0, o1, o2), c0, v0, v1, c1, result);
32064 
32065  if (synthesis_result)
32066  return result;
32067  else if (!expr_gen.valid_operator(o0,f0))
32068  return error_node();
32069 
32070  exprtk_debug(("c0 o0 (v0 o1 (v1 o2 c1))\n"));
32071 
32072  return node_type::allocate(*(expr_gen.node_allocator_), c0, v0, v1, c1, f0, f1, f2);
32073  }
32074 
32075  static inline std::string id(expression_generator<Type>& expr_gen,
32076  const details::operator_type o0,
32077  const details::operator_type o1,
32078  const details::operator_type o2)
32079  {
32080  return (details::build_string() << "t" << expr_gen.to_str(o0) << "(t" << expr_gen.to_str(o1) << "(t" << expr_gen.to_str(o2) << "t))");
32081  }
32082  };
32083 
32085  {
32086  typedef typename vococov_t::type1 node_type;
32087  typedef typename vococov_t::sf4_type sf4_type;
32088  typedef typename node_type::T0 T0;
32089  typedef typename node_type::T1 T1;
32090  typedef typename node_type::T2 T2;
32091  typedef typename node_type::T3 T3;
32092 
32094  const details::operator_type& operation,
32095  expression_node_ptr (&branch)[2])
32096  {
32097  // v0 o0 (c0 o1 (c1 o2 v1))
32098  typedef typename synthesize_cocov_expression1::node_type lcl_cocov_t;
32099 
32100  const lcl_cocov_t* cocov = static_cast<const lcl_cocov_t*>(branch[1]);
32101  const Type& v0 = static_cast<details::variable_node<Type>*>(branch[0])->ref();
32102  const Type c0 = cocov->t0();
32103  const Type c1 = cocov->t1();
32104  const Type& v1 = cocov->t2();
32105  const details::operator_type o0 = operation;
32106  const details::operator_type o1 = expr_gen.get_operator(cocov->f0());
32107  const details::operator_type o2 = expr_gen.get_operator(cocov->f1());
32108 
32109  binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
32110  binary_functor_t f1 = cocov->f0();
32111  binary_functor_t f2 = cocov->f1();
32112 
32113  details::free_node(*(expr_gen.node_allocator_),branch[1]);
32114 
32115  expression_node_ptr result = error_node();
32116 
32117  const bool synthesis_result =
32118  synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
32119  (expr_gen, id(expr_gen, o0, o1, o2), v0, c0, c1, v1, result);
32120 
32121  if (synthesis_result)
32122  return result;
32123  else if (!expr_gen.valid_operator(o0,f0))
32124  return error_node();
32125 
32126  exprtk_debug(("v0 o0 (c0 o1 (c1 o2 v1))\n"));
32127 
32128  return node_type::allocate(*(expr_gen.node_allocator_), v0, c0, c1, v1, f0, f1, f2);
32129  }
32130 
32131  static inline std::string id(expression_generator<Type>& expr_gen,
32132  const details::operator_type o0,
32133  const details::operator_type o1,
32134  const details::operator_type o2)
32135  {
32136  return (details::build_string() << "t" << expr_gen.to_str(o0) << "(t" << expr_gen.to_str(o1) << "(t" << expr_gen.to_str(o2) << "t))");
32137  }
32138  };
32139 
32141  {
32142  typedef typename vovovov_t::type2 node_type;
32143  typedef typename vovovov_t::sf4_type sf4_type;
32144  typedef typename node_type::T0 T0;
32145  typedef typename node_type::T1 T1;
32146  typedef typename node_type::T2 T2;
32147  typedef typename node_type::T3 T3;
32148 
32150  const details::operator_type& operation,
32151  expression_node_ptr (&branch)[2])
32152  {
32153  // v0 o0 ((v1 o1 v2) o2 v3)
32154  typedef typename synthesize_vovov_expression0::node_type lcl_vovov_t;
32155 
32156  const lcl_vovov_t* vovov = static_cast<const lcl_vovov_t*>(branch[1]);
32157  const Type& v0 = static_cast<details::variable_node<Type>*>(branch[0])->ref();
32158  const Type& v1 = vovov->t0();
32159  const Type& v2 = vovov->t1();
32160  const Type& v3 = vovov->t2();
32161  const details::operator_type o0 = operation;
32162  const details::operator_type o1 = expr_gen.get_operator(vovov->f0());
32163  const details::operator_type o2 = expr_gen.get_operator(vovov->f1());
32164 
32165  binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
32166  binary_functor_t f1 = vovov->f0();
32167  binary_functor_t f2 = vovov->f1();
32168 
32169  details::free_node(*(expr_gen.node_allocator_),branch[1]);
32170 
32171  expression_node_ptr result = error_node();
32172 
32173  const bool synthesis_result =
32174  synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
32175  (expr_gen, id(expr_gen, o0, o1, o2), v0, v1, v2, v3, result);
32176 
32177  if (synthesis_result)
32178  return result;
32179  else if (!expr_gen.valid_operator(o0,f0))
32180  return error_node();
32181 
32182  exprtk_debug(("v0 o0 ((v1 o1 v2) o2 v3)\n"));
32183 
32184  return node_type::allocate(*(expr_gen.node_allocator_), v0, v1, v2, v3, f0, f1, f2);
32185  }
32186 
32187  static inline std::string id(expression_generator<Type>& expr_gen,
32188  const details::operator_type o0,
32189  const details::operator_type o1,
32190  const details::operator_type o2)
32191  {
32192  return (details::build_string() << "t" << expr_gen.to_str(o0) << "((t" << expr_gen.to_str(o1) << "t)" << expr_gen.to_str(o2) << "t)");
32193  }
32194  };
32195 
32197  {
32198  typedef typename vovovoc_t::type2 node_type;
32199  typedef typename vovovoc_t::sf4_type sf4_type;
32200  typedef typename node_type::T0 T0;
32201  typedef typename node_type::T1 T1;
32202  typedef typename node_type::T2 T2;
32203  typedef typename node_type::T3 T3;
32204 
32206  const details::operator_type& operation,
32207  expression_node_ptr (&branch)[2])
32208  {
32209  // v0 o0 ((v1 o1 v2) o2 c)
32210  typedef typename synthesize_vovoc_expression0::node_type lcl_vovoc_t;
32211 
32212  const lcl_vovoc_t* vovoc = static_cast<const lcl_vovoc_t*>(branch[1]);
32213  const Type& v0 = static_cast<details::variable_node<Type>*>(branch[0])->ref();
32214  const Type& v1 = vovoc->t0();
32215  const Type& v2 = vovoc->t1();
32216  const Type c = vovoc->t2();
32217  const details::operator_type o0 = operation;
32218  const details::operator_type o1 = expr_gen.get_operator(vovoc->f0());
32219  const details::operator_type o2 = expr_gen.get_operator(vovoc->f1());
32220 
32221  binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
32222  binary_functor_t f1 = vovoc->f0();
32223  binary_functor_t f2 = vovoc->f1();
32224 
32225  details::free_node(*(expr_gen.node_allocator_),branch[1]);
32226 
32227  expression_node_ptr result = error_node();
32228 
32229  const bool synthesis_result =
32230  synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
32231  (expr_gen, id(expr_gen, o0, o1, o2), v0, v1, v2, c, result);
32232 
32233  if (synthesis_result)
32234  return result;
32235  else if (!expr_gen.valid_operator(o0,f0))
32236  return error_node();
32237 
32238  exprtk_debug(("v0 o0 ((v1 o1 v2) o2 c)\n"));
32239 
32240  return node_type::allocate(*(expr_gen.node_allocator_), v0, v1, v2, c, f0, f1, f2);
32241  }
32242 
32243  static inline std::string id(expression_generator<Type>& expr_gen,
32244  const details::operator_type o0,
32245  const details::operator_type o1,
32246  const details::operator_type o2)
32247  {
32248  return (details::build_string() << "t" << expr_gen.to_str(o0) << "((t" << expr_gen.to_str(o1) << "t)" << expr_gen.to_str(o2) << "t)");
32249  }
32250  };
32251 
32253  {
32254  typedef typename vovocov_t::type2 node_type;
32255  typedef typename vovocov_t::sf4_type sf4_type;
32256  typedef typename node_type::T0 T0;
32257  typedef typename node_type::T1 T1;
32258  typedef typename node_type::T2 T2;
32259  typedef typename node_type::T3 T3;
32260 
32262  const details::operator_type& operation,
32263  expression_node_ptr (&branch)[2])
32264  {
32265  // v0 o0 ((v1 o1 c) o2 v2)
32266  typedef typename synthesize_vocov_expression0::node_type lcl_vocov_t;
32267 
32268  const lcl_vocov_t* vocov = static_cast<const lcl_vocov_t*>(branch[1]);
32269  const Type& v0 = static_cast<details::variable_node<Type>*>(branch[0])->ref();
32270  const Type& v1 = vocov->t0();
32271  const Type c = vocov->t1();
32272  const Type& v2 = vocov->t2();
32273  const details::operator_type o0 = operation;
32274  const details::operator_type o1 = expr_gen.get_operator(vocov->f0());
32275  const details::operator_type o2 = expr_gen.get_operator(vocov->f1());
32276 
32277  binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
32278  binary_functor_t f1 = vocov->f0();
32279  binary_functor_t f2 = vocov->f1();
32280 
32281  details::free_node(*(expr_gen.node_allocator_),branch[1]);
32282 
32283  expression_node_ptr result = error_node();
32284 
32285  const bool synthesis_result =
32286  synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
32287  (expr_gen, id(expr_gen, o0, o1, o2), v0, v1, c, v2, result);
32288 
32289  if (synthesis_result)
32290  return result;
32291  else if (!expr_gen.valid_operator(o0,f0))
32292  return error_node();
32293 
32294  exprtk_debug(("v0 o0 ((v1 o1 c) o2 v2)\n"));
32295 
32296  return node_type::allocate(*(expr_gen.node_allocator_), v0, v1, c, v2, f0, f1, f2);
32297  }
32298 
32299  static inline std::string id(expression_generator<Type>& expr_gen,
32300  const details::operator_type o0,
32301  const details::operator_type o1,
32302  const details::operator_type o2)
32303  {
32304  return (details::build_string() << "t" << expr_gen.to_str(o0) << "((t" << expr_gen.to_str(o1) << "t)" << expr_gen.to_str(o2) << "t)");
32305  }
32306  };
32307 
32309  {
32310  typedef typename vocovov_t::type2 node_type;
32311  typedef typename vocovov_t::sf4_type sf4_type;
32312  typedef typename node_type::T0 T0;
32313  typedef typename node_type::T1 T1;
32314  typedef typename node_type::T2 T2;
32315  typedef typename node_type::T3 T3;
32316 
32318  const details::operator_type& operation,
32319  expression_node_ptr (&branch)[2])
32320  {
32321  // v0 o0 ((c o1 v1) o2 v2)
32322  typedef typename synthesize_covov_expression0::node_type lcl_covov_t;
32323 
32324  const lcl_covov_t* covov = static_cast<const lcl_covov_t*>(branch[1]);
32325  const Type& v0 = static_cast<details::variable_node<Type>*>(branch[0])->ref();
32326  const Type c = covov->t0();
32327  const Type& v1 = covov->t1();
32328  const Type& v2 = covov->t2();
32329  const details::operator_type o0 = operation;
32330  const details::operator_type o1 = expr_gen.get_operator(covov->f0());
32331  const details::operator_type o2 = expr_gen.get_operator(covov->f1());
32332 
32333  binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
32334  binary_functor_t f1 = covov->f0();
32335  binary_functor_t f2 = covov->f1();
32336 
32337  details::free_node(*(expr_gen.node_allocator_),branch[1]);
32338 
32339  expression_node_ptr result = error_node();
32340 
32341  const bool synthesis_result =
32342  synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
32343  (expr_gen, id(expr_gen, o0, o1, o2), v0, c, v1, v2, result);
32344 
32345  if (synthesis_result)
32346  return result;
32347  else if (!expr_gen.valid_operator(o0,f0))
32348  return error_node();
32349 
32350  exprtk_debug(("v0 o0 ((c o1 v1) o2 v2)\n"));
32351 
32352  return node_type::allocate(*(expr_gen.node_allocator_), v0, c, v1, v2, f0, f1, f2);
32353  }
32354 
32355  static inline std::string id(expression_generator<Type>& expr_gen,
32356  const details::operator_type o0,
32357  const details::operator_type o1,
32358  const details::operator_type o2)
32359  {
32360  return (details::build_string() << "t" << expr_gen.to_str(o0) << "((t" << expr_gen.to_str(o1) << "t)" << expr_gen.to_str(o2) << "t)");
32361  }
32362  };
32363 
32365  {
32366  typedef typename covovov_t::type2 node_type;
32367  typedef typename covovov_t::sf4_type sf4_type;
32368  typedef typename node_type::T0 T0;
32369  typedef typename node_type::T1 T1;
32370  typedef typename node_type::T2 T2;
32371  typedef typename node_type::T3 T3;
32372 
32374  const details::operator_type& operation,
32375  expression_node_ptr (&branch)[2])
32376  {
32377  // c o0 ((v1 o1 v2) o2 v3)
32378  typedef typename synthesize_vovov_expression0::node_type lcl_vovov_t;
32379 
32380  const lcl_vovov_t* vovov = static_cast<const lcl_vovov_t*>(branch[1]);
32381  const Type c = static_cast<details::literal_node<Type>*>(branch[0])->value();
32382  const Type& v0 = vovov->t0();
32383  const Type& v1 = vovov->t1();
32384  const Type& v2 = vovov->t2();
32385  const details::operator_type o0 = operation;
32386  const details::operator_type o1 = expr_gen.get_operator(vovov->f0());
32387  const details::operator_type o2 = expr_gen.get_operator(vovov->f1());
32388 
32389  binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
32390  binary_functor_t f1 = vovov->f0();
32391  binary_functor_t f2 = vovov->f1();
32392 
32393  details::free_node(*(expr_gen.node_allocator_),branch[0]);
32394  details::free_node(*(expr_gen.node_allocator_),branch[1]);
32395 
32396  expression_node_ptr result = error_node();
32397 
32398  const bool synthesis_result =
32399  synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
32400  (expr_gen, id(expr_gen, o0, o1, o2), c, v0, v1, v2, result);
32401 
32402  if (synthesis_result)
32403  return result;
32404  else if (!expr_gen.valid_operator(o0,f0))
32405  return error_node();
32406 
32407  exprtk_debug(("c o0 ((v1 o1 v2) o2 v3)\n"));
32408 
32409  return node_type::allocate(*(expr_gen.node_allocator_), c, v0, v1, v2, f0, f1, f2);
32410  }
32411 
32412  static inline std::string id(expression_generator<Type>& expr_gen,
32413  const details::operator_type o0,
32414  const details::operator_type o1,
32415  const details::operator_type o2)
32416  {
32417  return (details::build_string() << "t" << expr_gen.to_str(o0) << "((t" << expr_gen.to_str(o1) << "t)" << expr_gen.to_str(o2) << "t)");
32418  }
32419  };
32420 
32422  {
32423  typedef typename covocov_t::type2 node_type;
32424  typedef typename covocov_t::sf4_type sf4_type;
32425  typedef typename node_type::T0 T0;
32426  typedef typename node_type::T1 T1;
32427  typedef typename node_type::T2 T2;
32428  typedef typename node_type::T3 T3;
32429 
32431  const details::operator_type& operation,
32432  expression_node_ptr (&branch)[2])
32433  {
32434  // c0 o0 ((v0 o1 c1) o2 v1)
32435  typedef typename synthesize_vocov_expression0::node_type lcl_vocov_t;
32436 
32437  const lcl_vocov_t* vocov = static_cast<const lcl_vocov_t*>(branch[1]);
32438  const Type c0 = static_cast<details::literal_node<Type>*>(branch[0])->value();
32439  const Type& v0 = vocov->t0();
32440  const Type c1 = vocov->t1();
32441  const Type& v1 = vocov->t2();
32442  const details::operator_type o0 = operation;
32443  const details::operator_type o1 = expr_gen.get_operator(vocov->f0());
32444  const details::operator_type o2 = expr_gen.get_operator(vocov->f1());
32445 
32446  binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
32447  binary_functor_t f1 = vocov->f0();
32448  binary_functor_t f2 = vocov->f1();
32449 
32450  details::free_node(*(expr_gen.node_allocator_),branch[0]);
32451  details::free_node(*(expr_gen.node_allocator_),branch[1]);
32452 
32453  expression_node_ptr result = error_node();
32454 
32455  const bool synthesis_result =
32456  synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
32457  (expr_gen, id(expr_gen, o0, o1, o2), c0, v0, c1, v1, result);
32458 
32459  if (synthesis_result)
32460  return result;
32461  else if (!expr_gen.valid_operator(o0,f0))
32462  return error_node();
32463 
32464  exprtk_debug(("c0 o0 ((v0 o1 c1) o2 v1)\n"));
32465 
32466  return node_type::allocate(*(expr_gen.node_allocator_), c0, v0, c1, v1, f0, f1, f2);
32467  }
32468 
32469  static inline std::string id(expression_generator<Type>& expr_gen,
32470  const details::operator_type o0,
32471  const details::operator_type o1,
32472  const details::operator_type o2)
32473  {
32474  return (details::build_string() << "t" << expr_gen.to_str(o0) << "((t" << expr_gen.to_str(o1) << "t)" << expr_gen.to_str(o2) << "t)");
32475  }
32476  };
32477 
32479  {
32480  typedef typename vocovoc_t::type2 node_type;
32481  typedef typename vocovoc_t::sf4_type sf4_type;
32482  typedef typename node_type::T0 T0;
32483  typedef typename node_type::T1 T1;
32484  typedef typename node_type::T2 T2;
32485  typedef typename node_type::T3 T3;
32486 
32488  const details::operator_type& operation,
32489  expression_node_ptr (&branch)[2])
32490  {
32491  // v0 o0 ((c0 o1 v1) o2 c1)
32492  typedef typename synthesize_covoc_expression0::node_type lcl_covoc_t;
32493 
32494  const lcl_covoc_t* covoc = static_cast<const lcl_covoc_t*>(branch[1]);
32495  const Type& v0 = static_cast<details::variable_node<Type>*>(branch[0])->ref();
32496  const Type c0 = covoc->t0();
32497  const Type& v1 = covoc->t1();
32498  const Type c1 = covoc->t2();
32499  const details::operator_type o0 = operation;
32500  const details::operator_type o1 = expr_gen.get_operator(covoc->f0());
32501  const details::operator_type o2 = expr_gen.get_operator(covoc->f1());
32502 
32503  binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
32504  binary_functor_t f1 = covoc->f0();
32505  binary_functor_t f2 = covoc->f1();
32506 
32507  details::free_node(*(expr_gen.node_allocator_),branch[1]);
32508 
32509  expression_node_ptr result = error_node();
32510 
32511  const bool synthesis_result =
32512  synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
32513  (expr_gen, id(expr_gen, o0, o1, o2), v0, c0, v1, c1, result);
32514 
32515  if (synthesis_result)
32516  return result;
32517  else if (!expr_gen.valid_operator(o0,f0))
32518  return error_node();
32519 
32520  exprtk_debug(("v0 o0 ((c0 o1 v1) o2 c1)\n"));
32521 
32522  return node_type::allocate(*(expr_gen.node_allocator_), v0, c0, v1, c1, f0, f1, f2);
32523  }
32524 
32525  static inline std::string id(expression_generator<Type>& expr_gen,
32526  const details::operator_type o0,
32527  const details::operator_type o1,
32528  const details::operator_type o2)
32529  {
32530  return (details::build_string() << "t" << expr_gen.to_str(o0) << "((t" << expr_gen.to_str(o1) << "t)" << expr_gen.to_str(o2) << "t)");
32531  }
32532  };
32533 
32535  {
32536  typedef typename covovoc_t::type2 node_type;
32537  typedef typename covovoc_t::sf4_type sf4_type;
32538  typedef typename node_type::T0 T0;
32539  typedef typename node_type::T1 T1;
32540  typedef typename node_type::T2 T2;
32541  typedef typename node_type::T3 T3;
32542 
32544  const details::operator_type& operation,
32545  expression_node_ptr (&branch)[2])
32546  {
32547  // c0 o0 ((v0 o1 v1) o2 c1)
32548  typedef typename synthesize_vovoc_expression0::node_type lcl_vovoc_t;
32549 
32550  const lcl_vovoc_t* vovoc = static_cast<const lcl_vovoc_t*>(branch[1]);
32551  const Type c0 = static_cast<details::literal_node<Type>*>(branch[0])->value();
32552  const Type& v0 = vovoc->t0();
32553  const Type& v1 = vovoc->t1();
32554  const Type c1 = vovoc->t2();
32555  const details::operator_type o0 = operation;
32556  const details::operator_type o1 = expr_gen.get_operator(vovoc->f0());
32557  const details::operator_type o2 = expr_gen.get_operator(vovoc->f1());
32558 
32559  binary_functor_t f0 = reinterpret_cast<binary_functor_t>(0);
32560  binary_functor_t f1 = vovoc->f0();
32561  binary_functor_t f2 = vovoc->f1();
32562 
32563  details::free_node(*(expr_gen.node_allocator_),branch[0]);
32564  details::free_node(*(expr_gen.node_allocator_),branch[1]);
32565 
32566  expression_node_ptr result = error_node();
32567 
32568  const bool synthesis_result =
32569  synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
32570  (expr_gen, id(expr_gen, o0, o1, o2), c0, v0, v1, c1, result);
32571 
32572  if (synthesis_result)
32573  return result;
32574  else if (!expr_gen.valid_operator(o0,f0))
32575  return error_node();
32576 
32577  exprtk_debug(("c0 o0 ((v0 o1 v1) o2 c1)\n"));
32578 
32579  return node_type::allocate(*(expr_gen.node_allocator_), c0, v0, v1, c1, f0, f1, f2);
32580  }
32581 
32582  static inline std::string id(expression_generator<Type>& expr_gen,
32583  const details::operator_type o0,
32584  const details::operator_type o1,
32585  const details::operator_type o2)
32586  {
32587  return (details::build_string() << "t" << expr_gen.to_str(o0) << "((t" << expr_gen.to_str(o1) << "t)" << expr_gen.to_str(o2) << "t)");
32588  }
32589  };
32590 
32592  {
32593  typedef typename vococov_t::type2 node_type;
32595  {
32596  // v0 o0 ((c0 o1 c1) o2 v1) - Not possible
32597  exprtk_debug(("v0 o0 ((c0 o1 c1) o2 v1) - Not possible\n"));
32598  return error_node();
32599  }
32600 
32601  static inline std::string id(expression_generator<Type>&,
32603  {
32604  return "INVALID";
32605  }
32606  };
32607 
32609  {
32610  typedef typename vovovov_t::type3 node_type;
32611  typedef typename vovovov_t::sf4_type sf4_type;
32612  typedef typename node_type::T0 T0;
32613  typedef typename node_type::T1 T1;
32614  typedef typename node_type::T2 T2;
32615  typedef typename node_type::T3 T3;
32616 
32618  const details::operator_type& operation,
32619  expression_node_ptr (&branch)[2])
32620  {
32621  // ((v0 o0 v1) o1 v2) o2 v3
32622  typedef typename synthesize_vovov_expression0::node_type lcl_vovov_t;
32623 
32624  const lcl_vovov_t* vovov = static_cast<const lcl_vovov_t*>(branch[0]);
32625  const Type& v0 = vovov->t0();
32626  const Type& v1 = vovov->t1();
32627  const Type& v2 = vovov->t2();
32628  const Type& v3 = static_cast<details::variable_node<Type>*>(branch[1])->ref();
32629  const details::operator_type o0 = expr_gen.get_operator(vovov->f0());
32630  const details::operator_type o1 = expr_gen.get_operator(vovov->f1());
32631  const details::operator_type o2 = operation;
32632 
32633  binary_functor_t f0 = vovov->f0();
32634  binary_functor_t f1 = vovov->f1();
32635  binary_functor_t f2 = reinterpret_cast<binary_functor_t>(0);
32636 
32637  details::free_node(*(expr_gen.node_allocator_),branch[0]);
32638 
32639  expression_node_ptr result = error_node();
32640 
32641  const bool synthesis_result =
32642  synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
32643  (expr_gen, id(expr_gen, o0, o1, o2), v0, v1, v2, v3, result);
32644 
32645  if (synthesis_result)
32646  return result;
32647  else if (!expr_gen.valid_operator(o2,f2))
32648  return error_node();
32649 
32650  exprtk_debug(("((v0 o0 v1) o1 v2) o2 v3\n"));
32651 
32652  return node_type::allocate(*(expr_gen.node_allocator_), v0, v1, v2, v3, f0, f1, f2);
32653  }
32654 
32655  static inline std::string id(expression_generator<Type>& expr_gen,
32656  const details::operator_type o0,
32657  const details::operator_type o1,
32658  const details::operator_type o2)
32659  {
32660  return (details::build_string() << "((t" << expr_gen.to_str(o0) << "t)" << expr_gen.to_str(o1) << "t)" << expr_gen.to_str(o2) << "t");
32661  }
32662  };
32663 
32665  {
32666  typedef typename vovovoc_t::type3 node_type;
32667  typedef typename vovovoc_t::sf4_type sf4_type;
32668  typedef typename node_type::T0 T0;
32669  typedef typename node_type::T1 T1;
32670  typedef typename node_type::T2 T2;
32671  typedef typename node_type::T3 T3;
32672 
32674  const details::operator_type& operation,
32675  expression_node_ptr (&branch)[2])
32676  {
32677  // ((v0 o0 v1) o1 v2) o2 c
32678  typedef typename synthesize_vovov_expression0::node_type lcl_vovov_t;
32679 
32680  const lcl_vovov_t* vovov = static_cast<const lcl_vovov_t*>(branch[0]);
32681  const Type& v0 = vovov->t0();
32682  const Type& v1 = vovov->t1();
32683  const Type& v2 = vovov->t2();
32684  const Type c = static_cast<details::literal_node<Type>*>(branch[1])->value();
32685  const details::operator_type o0 = expr_gen.get_operator(vovov->f0());
32686  const details::operator_type o1 = expr_gen.get_operator(vovov->f1());
32687  const details::operator_type o2 = operation;
32688 
32689  binary_functor_t f0 = vovov->f0();
32690  binary_functor_t f1 = vovov->f1();
32691  binary_functor_t f2 = reinterpret_cast<binary_functor_t>(0);
32692 
32693  details::free_node(*(expr_gen.node_allocator_),branch[0]);
32694  details::free_node(*(expr_gen.node_allocator_),branch[1]);
32695 
32696  expression_node_ptr result = error_node();
32697 
32698  const bool synthesis_result =
32699  synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
32700  (expr_gen, id(expr_gen, o0, o1, o2), v0, v1, v2, c, result);
32701 
32702  if (synthesis_result)
32703  return result;
32704  else if (!expr_gen.valid_operator(o2,f2))
32705  return error_node();
32706 
32707  exprtk_debug(("((v0 o0 v1) o1 v2) o2 c\n"));
32708 
32709  return node_type::allocate(*(expr_gen.node_allocator_), v0, v1, v2, c, f0, f1, f2);
32710  }
32711 
32712  static inline std::string id(expression_generator<Type>& expr_gen,
32713  const details::operator_type o0,
32714  const details::operator_type o1,
32715  const details::operator_type o2)
32716  {
32717  return (details::build_string() << "((t" << expr_gen.to_str(o0) << "t)" << expr_gen.to_str(o1) << "t)" << expr_gen.to_str(o2) << "t");
32718  }
32719  };
32720 
32722  {
32723  typedef typename vovocov_t::type3 node_type;
32724  typedef typename vovocov_t::sf4_type sf4_type;
32725  typedef typename node_type::T0 T0;
32726  typedef typename node_type::T1 T1;
32727  typedef typename node_type::T2 T2;
32728  typedef typename node_type::T3 T3;
32729 
32731  const details::operator_type& operation,
32732  expression_node_ptr (&branch)[2])
32733  {
32734  // ((v0 o0 v1) o1 c) o2 v2
32735  typedef typename synthesize_vovoc_expression0::node_type lcl_vovoc_t;
32736 
32737  const lcl_vovoc_t* vovoc = static_cast<const lcl_vovoc_t*>(branch[0]);
32738  const Type& v0 = vovoc->t0();
32739  const Type& v1 = vovoc->t1();
32740  const Type c = vovoc->t2();
32741  const Type& v2 = static_cast<details::variable_node<Type>*>(branch[1])->ref();
32742  const details::operator_type o0 = expr_gen.get_operator(vovoc->f0());
32743  const details::operator_type o1 = expr_gen.get_operator(vovoc->f1());
32744  const details::operator_type o2 = operation;
32745 
32746  binary_functor_t f0 = vovoc->f0();
32747  binary_functor_t f1 = vovoc->f1();
32748  binary_functor_t f2 = reinterpret_cast<binary_functor_t>(0);
32749 
32750  details::free_node(*(expr_gen.node_allocator_),branch[0]);
32751 
32752  expression_node_ptr result = error_node();
32753 
32754  const bool synthesis_result =
32755  synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
32756  (expr_gen, id(expr_gen, o0, o1, o2), v0, v1, c, v2, result);
32757 
32758  if (synthesis_result)
32759  return result;
32760  else if (!expr_gen.valid_operator(o2,f2))
32761  return error_node();
32762 
32763  exprtk_debug(("((v0 o0 v1) o1 c) o2 v2\n"));
32764 
32765  return node_type::allocate(*(expr_gen.node_allocator_), v0, v1, c, v2, f0, f1, f2);
32766  }
32767 
32768  static inline std::string id(expression_generator<Type>& expr_gen,
32769  const details::operator_type o0,
32770  const details::operator_type o1,
32771  const details::operator_type o2)
32772  {
32773  return (details::build_string() << "((t" << expr_gen.to_str(o0) << "t)" << expr_gen.to_str(o1) << "t)" << expr_gen.to_str(o2) << "t");
32774  }
32775  };
32776 
32778  {
32779  typedef typename vocovov_t::type3 node_type;
32780  typedef typename vocovov_t::sf4_type sf4_type;
32781  typedef typename node_type::T0 T0;
32782  typedef typename node_type::T1 T1;
32783  typedef typename node_type::T2 T2;
32784  typedef typename node_type::T3 T3;
32785 
32787  const details::operator_type& operation,
32788  expression_node_ptr (&branch)[2])
32789  {
32790  // ((v0 o0 c) o1 v1) o2 v2
32791  typedef typename synthesize_vocov_expression0::node_type lcl_vocov_t;
32792 
32793  const lcl_vocov_t* vocov = static_cast<const lcl_vocov_t*>(branch[0]);
32794  const Type& v0 = vocov->t0();
32795  const Type c = vocov->t1();
32796  const Type& v1 = vocov->t2();
32797  const Type& v2 = static_cast<details::variable_node<Type>*>(branch[1])->ref();
32798  const details::operator_type o0 = expr_gen.get_operator(vocov->f0());
32799  const details::operator_type o1 = expr_gen.get_operator(vocov->f1());
32800  const details::operator_type o2 = operation;
32801 
32802  binary_functor_t f0 = vocov->f0();
32803  binary_functor_t f1 = vocov->f1();
32804  binary_functor_t f2 = reinterpret_cast<binary_functor_t>(0);
32805 
32806  details::free_node(*(expr_gen.node_allocator_),branch[0]);
32807 
32808  expression_node_ptr result = error_node();
32809 
32810  const bool synthesis_result =
32811  synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
32812  (expr_gen, id(expr_gen, o0, o1, o2), v0, c, v1, v2, result);
32813 
32814  if (synthesis_result)
32815  return result;
32816  else if (!expr_gen.valid_operator(o2,f2))
32817  return error_node();
32818 
32819  exprtk_debug(("((v0 o0 c) o1 v1) o2 v2\n"));
32820 
32821  return node_type::allocate(*(expr_gen.node_allocator_), v0, c, v1, v2, f0, f1, f2);
32822  }
32823 
32824  static inline std::string id(expression_generator<Type>& expr_gen,
32825  const details::operator_type o0,
32826  const details::operator_type o1,
32827  const details::operator_type o2)
32828  {
32829  return (details::build_string() << "((t" << expr_gen.to_str(o0) << "t)" << expr_gen.to_str(o1) << "t)" << expr_gen.to_str(o2) << "t");
32830  }
32831  };
32832 
32834  {
32835  typedef typename covovov_t::type3 node_type;
32836  typedef typename covovov_t::sf4_type sf4_type;
32837  typedef typename node_type::T0 T0;
32838  typedef typename node_type::T1 T1;
32839  typedef typename node_type::T2 T2;
32840  typedef typename node_type::T3 T3;
32841 
32843  const details::operator_type& operation,
32844  expression_node_ptr (&branch)[2])
32845  {
32846  // ((c o0 v0) o1 v1) o2 v2
32847  typedef typename synthesize_covov_expression0::node_type lcl_covov_t;
32848 
32849  const lcl_covov_t* covov = static_cast<const lcl_covov_t*>(branch[0]);
32850  const Type c = covov->t0();
32851  const Type& v0 = covov->t1();
32852  const Type& v1 = covov->t2();
32853  const Type& v2 = static_cast<details::variable_node<Type>*>(branch[1])->ref();
32854  const details::operator_type o0 = expr_gen.get_operator(covov->f0());
32855  const details::operator_type o1 = expr_gen.get_operator(covov->f1());
32856  const details::operator_type o2 = operation;
32857 
32858  binary_functor_t f0 = covov->f0();
32859  binary_functor_t f1 = covov->f1();
32860  binary_functor_t f2 = reinterpret_cast<binary_functor_t>(0);
32861 
32862  details::free_node(*(expr_gen.node_allocator_),branch[0]);
32863 
32864  expression_node_ptr result = error_node();
32865 
32866  const bool synthesis_result =
32867  synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
32868  (expr_gen, id(expr_gen, o0, o1, o2), c, v0, v1, v2, result);
32869 
32870  if (synthesis_result)
32871  return result;
32872  else if (!expr_gen.valid_operator(o2,f2))
32873  return error_node();
32874 
32875  exprtk_debug(("((c o0 v0) o1 v1) o2 v2\n"));
32876 
32877  return node_type::allocate(*(expr_gen.node_allocator_), c, v0, v1, v2, f0, f1, f2);
32878  }
32879 
32880  static inline std::string id(expression_generator<Type>& expr_gen,
32881  const details::operator_type o0,
32882  const details::operator_type o1,
32883  const details::operator_type o2)
32884  {
32885  return (details::build_string() << "((t" << expr_gen.to_str(o0) << "t)" << expr_gen.to_str(o1) << "t)" << expr_gen.to_str(o2) << "t");
32886  }
32887  };
32888 
32890  {
32891  typedef typename covocov_t::type3 node_type;
32892  typedef typename covocov_t::sf4_type sf4_type;
32893  typedef typename node_type::T0 T0;
32894  typedef typename node_type::T1 T1;
32895  typedef typename node_type::T2 T2;
32896  typedef typename node_type::T3 T3;
32897 
32899  const details::operator_type& operation,
32900  expression_node_ptr (&branch)[2])
32901  {
32902  // ((c0 o0 v0) o1 c1) o2 v1
32903  typedef typename synthesize_covoc_expression0::node_type lcl_covoc_t;
32904 
32905  const lcl_covoc_t* covoc = static_cast<const lcl_covoc_t*>(branch[0]);
32906  const Type c0 = covoc->t0();
32907  const Type& v0 = covoc->t1();
32908  const Type c1 = covoc->t2();
32909  const Type& v1 = static_cast<details::variable_node<Type>*>(branch[1])->ref();
32910  const details::operator_type o0 = expr_gen.get_operator(covoc->f0());
32911  const details::operator_type o1 = expr_gen.get_operator(covoc->f1());
32912  const details::operator_type o2 = operation;
32913 
32914  binary_functor_t f0 = covoc->f0();
32915  binary_functor_t f1 = covoc->f1();
32916  binary_functor_t f2 = reinterpret_cast<binary_functor_t>(0);
32917 
32918  details::free_node(*(expr_gen.node_allocator_),branch[0]);
32919 
32920  expression_node_ptr result = error_node();
32921 
32922  const bool synthesis_result =
32923  synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
32924  (expr_gen, id(expr_gen, o0, o1, o2), c0, v0, c1, v1, result);
32925 
32926  if (synthesis_result)
32927  return result;
32928  else if (!expr_gen.valid_operator(o2,f2))
32929  return error_node();
32930 
32931  exprtk_debug(("((c0 o0 v0) o1 c1) o2 v1\n"));
32932 
32933  return node_type::allocate(*(expr_gen.node_allocator_), c0, v0, c1, v1, f0, f1, f2);
32934  }
32935 
32936  static inline std::string id(expression_generator<Type>& expr_gen,
32937  const details::operator_type o0,
32938  const details::operator_type o1,
32939  const details::operator_type o2)
32940  {
32941  return (details::build_string() << "((t" << expr_gen.to_str(o0) << "t)" << expr_gen.to_str(o1) << "t)" << expr_gen.to_str(o2) << "t");
32942  }
32943  };
32944 
32946  {
32947  typedef typename vocovoc_t::type3 node_type;
32948  typedef typename vocovoc_t::sf4_type sf4_type;
32949  typedef typename node_type::T0 T0;
32950  typedef typename node_type::T1 T1;
32951  typedef typename node_type::T2 T2;
32952  typedef typename node_type::T3 T3;
32953 
32955  const details::operator_type& operation,
32956  expression_node_ptr (&branch)[2])
32957  {
32958  // ((v0 o0 c0) o1 v1) o2 c1
32959  typedef typename synthesize_vocov_expression0::node_type lcl_vocov_t;
32960 
32961  const lcl_vocov_t* vocov = static_cast<const lcl_vocov_t*>(branch[0]);
32962  const Type& v0 = vocov->t0();
32963  const Type c0 = vocov->t1();
32964  const Type& v1 = vocov->t2();
32965  const Type c1 = static_cast<details::literal_node<Type>*>(branch[1])->value();
32966  const details::operator_type o0 = expr_gen.get_operator(vocov->f0());
32967  const details::operator_type o1 = expr_gen.get_operator(vocov->f1());
32968  const details::operator_type o2 = operation;
32969 
32970  binary_functor_t f0 = vocov->f0();
32971  binary_functor_t f1 = vocov->f1();
32972  binary_functor_t f2 = reinterpret_cast<binary_functor_t>(0);
32973 
32974  details::free_node(*(expr_gen.node_allocator_),branch[0]);
32975  details::free_node(*(expr_gen.node_allocator_),branch[1]);
32976 
32977  expression_node_ptr result = error_node();
32978 
32979  const bool synthesis_result =
32980  synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
32981  (expr_gen, id(expr_gen, o0, o1, o2), v0, c0, v1, c1, result);
32982 
32983  if (synthesis_result)
32984  return result;
32985  else if (!expr_gen.valid_operator(o2,f2))
32986  return error_node();
32987 
32988  exprtk_debug(("((v0 o0 c0) o1 v1) o2 c1\n"));
32989 
32990  return node_type::allocate(*(expr_gen.node_allocator_), v0, c0, v1, c1, f0, f1, f2);
32991  }
32992 
32993  static inline std::string id(expression_generator<Type>& expr_gen,
32994  const details::operator_type o0,
32995  const details::operator_type o1,
32996  const details::operator_type o2)
32997  {
32998  return (details::build_string() << "((t" << expr_gen.to_str(o0) << "t)" << expr_gen.to_str(o1) << "t)" << expr_gen.to_str(o2) << "t");
32999  }
33000  };
33001 
33003  {
33004  typedef typename covovoc_t::type3 node_type;
33005  typedef typename covovoc_t::sf4_type sf4_type;
33006  typedef typename node_type::T0 T0;
33007  typedef typename node_type::T1 T1;
33008  typedef typename node_type::T2 T2;
33009  typedef typename node_type::T3 T3;
33010 
33012  const details::operator_type& operation,
33013  expression_node_ptr (&branch)[2])
33014  {
33015  // ((c0 o0 v0) o1 v1) o2 c1
33016  typedef typename synthesize_covov_expression0::node_type lcl_covov_t;
33017 
33018  const lcl_covov_t* covov = static_cast<const lcl_covov_t*>(branch[0]);
33019  const Type c0 = covov->t0();
33020  const Type& v0 = covov->t1();
33021  const Type& v1 = covov->t2();
33022  const Type c1 = static_cast<details::literal_node<Type>*>(branch[1])->value();
33023  const details::operator_type o0 = expr_gen.get_operator(covov->f0());
33024  const details::operator_type o1 = expr_gen.get_operator(covov->f1());
33025  const details::operator_type o2 = operation;
33026 
33027  binary_functor_t f0 = covov->f0();
33028  binary_functor_t f1 = covov->f1();
33029  binary_functor_t f2 = reinterpret_cast<binary_functor_t>(0);
33030 
33031  details::free_node(*(expr_gen.node_allocator_),branch[0]);
33032  details::free_node(*(expr_gen.node_allocator_),branch[1]);
33033 
33034  expression_node_ptr result = error_node();
33035 
33036  const bool synthesis_result =
33037  synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
33038  (expr_gen, id(expr_gen, o0, o1, o2), c0, v0, v1, c1, result);
33039 
33040  if (synthesis_result)
33041  return result;
33042  else if (!expr_gen.valid_operator(o2,f2))
33043  return error_node();
33044 
33045  exprtk_debug(("((c0 o0 v0) o1 v1) o2 c1\n"));
33046 
33047  return node_type::allocate(*(expr_gen.node_allocator_), c0, v0, v1, c1, f0, f1, f2);
33048  }
33049 
33050  static inline std::string id(expression_generator<Type>& expr_gen,
33051  const details::operator_type o0,
33052  const details::operator_type o1,
33053  const details::operator_type o2)
33054  {
33055  return (details::build_string() << "((t" << expr_gen.to_str(o0) << "t)" << expr_gen.to_str(o1) << "t)" << expr_gen.to_str(o2) << "t");
33056  }
33057  };
33058 
33060  {
33061  typedef typename vococov_t::type3 node_type;
33062  typedef typename vococov_t::sf4_type sf4_type;
33063  typedef typename node_type::T0 T0;
33064  typedef typename node_type::T1 T1;
33065  typedef typename node_type::T2 T2;
33066  typedef typename node_type::T3 T3;
33067 
33069  const details::operator_type& operation,
33070  expression_node_ptr (&branch)[2])
33071  {
33072  // ((v0 o0 c0) o1 c1) o2 v1
33073  typedef typename synthesize_vococ_expression0::node_type lcl_vococ_t;
33074 
33075  const lcl_vococ_t* vococ = static_cast<const lcl_vococ_t*>(branch[0]);
33076  const Type& v0 = vococ->t0();
33077  const Type c0 = vococ->t1();
33078  const Type c1 = vococ->t2();
33079  const Type& v1 = static_cast<details::variable_node<Type>*>(branch[1])->ref();
33080  const details::operator_type o0 = expr_gen.get_operator(vococ->f0());
33081  const details::operator_type o1 = expr_gen.get_operator(vococ->f1());
33082  const details::operator_type o2 = operation;
33083 
33084  binary_functor_t f0 = vococ->f0();
33085  binary_functor_t f1 = vococ->f1();
33086  binary_functor_t f2 = reinterpret_cast<binary_functor_t>(0);
33087 
33088  details::free_node(*(expr_gen.node_allocator_),branch[0]);
33089 
33090  expression_node_ptr result = error_node();
33091 
33092  const bool synthesis_result =
33093  synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
33094  (expr_gen, id(expr_gen, o0, o1, o2), v0, c0, c1, v1, result);
33095 
33096  if (synthesis_result)
33097  return result;
33098  else if (!expr_gen.valid_operator(o2,f2))
33099  return error_node();
33100 
33101  exprtk_debug(("((v0 o0 c0) o1 c1) o2 v1\n"));
33102 
33103  return node_type::allocate(*(expr_gen.node_allocator_), v0, c0, c1, v1, f0, f1, f2);
33104  }
33105 
33106  static inline std::string id(expression_generator<Type>& expr_gen,
33107  const details::operator_type o0,
33108  const details::operator_type o1,
33109  const details::operator_type o2)
33110  {
33111  return (details::build_string() << "((t" << expr_gen.to_str(o0) << "t)" << expr_gen.to_str(o1) << "t)" << expr_gen.to_str(o2) << "t");
33112  }
33113  };
33114 
33116  {
33117  typedef typename vovovov_t::type4 node_type;
33118  typedef typename vovovov_t::sf4_type sf4_type;
33119  typedef typename node_type::T0 T0;
33120  typedef typename node_type::T1 T1;
33121  typedef typename node_type::T2 T2;
33122  typedef typename node_type::T3 T3;
33123 
33125  const details::operator_type& operation,
33126  expression_node_ptr (&branch)[2])
33127  {
33128  // (v0 o0 (v1 o1 v2)) o2 v3
33129  typedef typename synthesize_vovov_expression1::node_type lcl_vovov_t;
33130 
33131  const lcl_vovov_t* vovov = static_cast<const lcl_vovov_t*>(branch[0]);
33132  const Type& v0 = vovov->t0();
33133  const Type& v1 = vovov->t1();
33134  const Type& v2 = vovov->t2();
33135  const Type& v3 = static_cast<details::variable_node<Type>*>(branch[1])->ref();
33136  const details::operator_type o0 = expr_gen.get_operator(vovov->f0());
33137  const details::operator_type o1 = expr_gen.get_operator(vovov->f1());
33138  const details::operator_type o2 = operation;
33139 
33140  binary_functor_t f0 = vovov->f0();
33141  binary_functor_t f1 = vovov->f1();
33142  binary_functor_t f2 = reinterpret_cast<binary_functor_t>(0);
33143 
33144  details::free_node(*(expr_gen.node_allocator_),branch[0]);
33145 
33146  expression_node_ptr result = error_node();
33147 
33148  const bool synthesis_result =
33149  synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
33150  (expr_gen, id(expr_gen, o0, o1, o2), v0, v1, v2, v3, result);
33151 
33152  if (synthesis_result)
33153  return result;
33154  else if (!expr_gen.valid_operator(o2,f2))
33155  return error_node();
33156 
33157  exprtk_debug(("(v0 o0 (v1 o1 v2)) o2 v3\n"));
33158 
33159  return node_type::allocate(*(expr_gen.node_allocator_), v0, v1, v2, v3, f0, f1, f2);
33160  }
33161 
33162  static inline std::string id(expression_generator<Type>& expr_gen,
33163  const details::operator_type o0,
33164  const details::operator_type o1,
33165  const details::operator_type o2)
33166  {
33167  return (details::build_string() << "(t" << expr_gen.to_str(o0) << "(t" << expr_gen.to_str(o1) << "t)" << expr_gen.to_str(o2) << "t");
33168  }
33169  };
33170 
33172  {
33173  typedef typename vovovoc_t::type4 node_type;
33174  typedef typename vovovoc_t::sf4_type sf4_type;
33175  typedef typename node_type::T0 T0;
33176  typedef typename node_type::T1 T1;
33177  typedef typename node_type::T2 T2;
33178  typedef typename node_type::T3 T3;
33179 
33181  const details::operator_type& operation,
33182  expression_node_ptr (&branch)[2])
33183  {
33184  // ((v0 o0 (v1 o1 v2)) o2 c)
33185  typedef typename synthesize_vovov_expression1::node_type lcl_vovov_t;
33186 
33187  const lcl_vovov_t* vovov = static_cast<const lcl_vovov_t*>(branch[0]);
33188  const Type& v0 = vovov->t0();
33189  const Type& v1 = vovov->t1();
33190  const Type& v2 = vovov->t2();
33191  const Type c = static_cast<details::literal_node<Type>*>(branch[1])->value();
33192  const details::operator_type o0 = expr_gen.get_operator(vovov->f0());
33193  const details::operator_type o1 = expr_gen.get_operator(vovov->f1());
33194  const details::operator_type o2 = operation;
33195 
33196  binary_functor_t f0 = vovov->f0();
33197  binary_functor_t f1 = vovov->f1();
33198  binary_functor_t f2 = reinterpret_cast<binary_functor_t>(0);
33199 
33200  details::free_node(*(expr_gen.node_allocator_),branch[0]);
33201  details::free_node(*(expr_gen.node_allocator_),branch[1]);
33202 
33203  expression_node_ptr result = error_node();
33204 
33205  const bool synthesis_result =
33206  synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
33207  (expr_gen, id(expr_gen, o0, o1, o2), v0, v1, v2, c, result);
33208 
33209  if (synthesis_result)
33210  return result;
33211  else if (!expr_gen.valid_operator(o2,f2))
33212  return error_node();
33213 
33214  exprtk_debug(("((v0 o0 (v1 o1 v2)) o2 c)\n"));
33215 
33216  return node_type::allocate(*(expr_gen.node_allocator_), v0, v1, v2, c, f0, f1, f2);
33217  }
33218 
33219  static inline std::string id(expression_generator<Type>& expr_gen,
33220  const details::operator_type o0,
33221  const details::operator_type o1,
33222  const details::operator_type o2)
33223  {
33224  return (details::build_string() << "(t" << expr_gen.to_str(o0) << "(t" << expr_gen.to_str(o1) << "t)" << expr_gen.to_str(o2) << "t");
33225  }
33226  };
33227 
33229  {
33230  typedef typename vovocov_t::type4 node_type;
33231  typedef typename vovocov_t::sf4_type sf4_type;
33232  typedef typename node_type::T0 T0;
33233  typedef typename node_type::T1 T1;
33234  typedef typename node_type::T2 T2;
33235  typedef typename node_type::T3 T3;
33236 
33238  const details::operator_type& operation,
33239  expression_node_ptr (&branch)[2])
33240  {
33241  // ((v0 o0 (v1 o1 c)) o2 v1)
33242  typedef typename synthesize_vovoc_expression1::node_type lcl_vovoc_t;
33243 
33244  const lcl_vovoc_t* vovoc = static_cast<const lcl_vovoc_t*>(branch[0]);
33245  const Type& v0 = vovoc->t0();
33246  const Type& v1 = vovoc->t1();
33247  const Type c = vovoc->t2();
33248  const Type& v2 = static_cast<details::variable_node<Type>*>(branch[1])->ref();
33249  const details::operator_type o0 = expr_gen.get_operator(vovoc->f0());
33250  const details::operator_type o1 = expr_gen.get_operator(vovoc->f1());
33251  const details::operator_type o2 = operation;
33252 
33253  binary_functor_t f0 = vovoc->f0();
33254  binary_functor_t f1 = vovoc->f1();
33255  binary_functor_t f2 = reinterpret_cast<binary_functor_t>(0);
33256 
33257  details::free_node(*(expr_gen.node_allocator_),branch[0]);
33258 
33259  expression_node_ptr result = error_node();
33260 
33261  const bool synthesis_result =
33262  synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
33263  (expr_gen, id(expr_gen, o0, o1, o2), v0, v1, c, v2, result);
33264 
33265  if (synthesis_result)
33266  return result;
33267  else if (!expr_gen.valid_operator(o2,f2))
33268  return error_node();
33269 
33270  exprtk_debug(("((v0 o0 (v1 o1 c)) o2 v1)\n"));
33271 
33272  return node_type::allocate(*(expr_gen.node_allocator_), v0, v1, c, v2, f0, f1, f2);
33273  }
33274 
33275  static inline std::string id(expression_generator<Type>& expr_gen,
33276  const details::operator_type o0,
33277  const details::operator_type o1,
33278  const details::operator_type o2)
33279  {
33280  return (details::build_string() << "(t" << expr_gen.to_str(o0) << "(t" << expr_gen.to_str(o1) << "t)" << expr_gen.to_str(o2) << "t");
33281  }
33282  };
33283 
33285  {
33286  typedef typename vocovov_t::type4 node_type;
33287  typedef typename vocovov_t::sf4_type sf4_type;
33288  typedef typename node_type::T0 T0;
33289  typedef typename node_type::T1 T1;
33290  typedef typename node_type::T2 T2;
33291  typedef typename node_type::T3 T3;
33292 
33294  const details::operator_type& operation,
33295  expression_node_ptr (&branch)[2])
33296  {
33297  // ((v0 o0 (c o1 v1)) o2 v2)
33298  typedef typename synthesize_vocov_expression1::node_type lcl_vocov_t;
33299 
33300  const lcl_vocov_t* vocov = static_cast<const lcl_vocov_t*>(branch[0]);
33301  const Type& v0 = vocov->t0();
33302  const Type c = vocov->t1();
33303  const Type& v1 = vocov->t2();
33304  const Type& v2 = static_cast<details::variable_node<Type>*>(branch[1])->ref();
33305  const details::operator_type o0 = expr_gen.get_operator(vocov->f0());
33306  const details::operator_type o1 = expr_gen.get_operator(vocov->f1());
33307  const details::operator_type o2 = operation;
33308 
33309  binary_functor_t f0 = vocov->f0();
33310  binary_functor_t f1 = vocov->f1();
33311  binary_functor_t f2 = reinterpret_cast<binary_functor_t>(0);
33312 
33313  details::free_node(*(expr_gen.node_allocator_),branch[0]);
33314  expression_node_ptr result = error_node();
33315 
33316  const bool synthesis_result =
33317  synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
33318  (expr_gen, id(expr_gen, o0, o1, o2), v0, c, v1, v2, result);
33319 
33320  if (synthesis_result)
33321  return result;
33322  else if (!expr_gen.valid_operator(o2,f2))
33323  return error_node();
33324 
33325  exprtk_debug(("((v0 o0 (c o1 v1)) o2 v2)\n"));
33326 
33327  return node_type::allocate(*(expr_gen.node_allocator_), v0, c, v1, v2, f0, f1, f2);
33328  }
33329 
33330  static inline std::string id(expression_generator<Type>& expr_gen,
33331  const details::operator_type o0,
33332  const details::operator_type o1,
33333  const details::operator_type o2)
33334  {
33335  return (details::build_string() << "(t" << expr_gen.to_str(o0) << "(t" << expr_gen.to_str(o1) << "t)" << expr_gen.to_str(o2) << "t");
33336  }
33337  };
33338 
33340  {
33341  typedef typename covovov_t::type4 node_type;
33342  typedef typename covovov_t::sf4_type sf4_type;
33343  typedef typename node_type::T0 T0;
33344  typedef typename node_type::T1 T1;
33345  typedef typename node_type::T2 T2;
33346  typedef typename node_type::T3 T3;
33347 
33349  const details::operator_type& operation,
33350  expression_node_ptr (&branch)[2])
33351  {
33352  // ((c o0 (v0 o1 v1)) o2 v2)
33353  typedef typename synthesize_covov_expression1::node_type lcl_covov_t;
33354 
33355  const lcl_covov_t* covov = static_cast<const lcl_covov_t*>(branch[0]);
33356  const Type c = covov->t0();
33357  const Type& v0 = covov->t1();
33358  const Type& v1 = covov->t2();
33359  const Type& v2 = static_cast<details::variable_node<Type>*>(branch[1])->ref();
33360  const details::operator_type o0 = expr_gen.get_operator(covov->f0());
33361  const details::operator_type o1 = expr_gen.get_operator(covov->f1());
33362  const details::operator_type o2 = operation;
33363 
33364  binary_functor_t f0 = covov->f0();
33365  binary_functor_t f1 = covov->f1();
33366  binary_functor_t f2 = reinterpret_cast<binary_functor_t>(0);
33367 
33368  details::free_node(*(expr_gen.node_allocator_),branch[0]);
33369 
33370  expression_node_ptr result = error_node();
33371 
33372  const bool synthesis_result =
33373  synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
33374  (expr_gen, id(expr_gen, o0, o1, o2), c, v0, v1, v2, result);
33375 
33376  if (synthesis_result)
33377  return result;
33378  else if (!expr_gen.valid_operator(o2,f2))
33379  return error_node();
33380 
33381  exprtk_debug(("((c o0 (v0 o1 v1)) o2 v2)\n"));
33382 
33383  return node_type::allocate(*(expr_gen.node_allocator_), c, v0, v1, v2, f0, f1, f2);
33384  }
33385 
33386  static inline std::string id(expression_generator<Type>& expr_gen,
33387  const details::operator_type o0,
33388  const details::operator_type o1,
33389  const details::operator_type o2)
33390  {
33391  return (details::build_string() << "(t" << expr_gen.to_str(o0) << "(t" << expr_gen.to_str(o1) << "t)" << expr_gen.to_str(o2) << "t");
33392  }
33393  };
33394 
33396  {
33397  typedef typename covocov_t::type4 node_type;
33398  typedef typename covocov_t::sf4_type sf4_type;
33399  typedef typename node_type::T0 T0;
33400  typedef typename node_type::T1 T1;
33401  typedef typename node_type::T2 T2;
33402  typedef typename node_type::T3 T3;
33403 
33405  const details::operator_type& operation,
33406  expression_node_ptr (&branch)[2])
33407  {
33408  // ((c0 o0 (v0 o1 c1)) o2 v1)
33409  typedef typename synthesize_covoc_expression1::node_type lcl_covoc_t;
33410 
33411  const lcl_covoc_t* covoc = static_cast<const lcl_covoc_t*>(branch[0]);
33412  const Type c0 = covoc->t0();
33413  const Type& v0 = covoc->t1();
33414  const Type c1 = covoc->t2();
33415  const Type& v1 = static_cast<details::variable_node<Type>*>(branch[1])->ref();
33416  const details::operator_type o0 = expr_gen.get_operator(covoc->f0());
33417  const details::operator_type o1 = expr_gen.get_operator(covoc->f1());
33418  const details::operator_type o2 = operation;
33419 
33420  binary_functor_t f0 = covoc->f0();
33421  binary_functor_t f1 = covoc->f1();
33422  binary_functor_t f2 = reinterpret_cast<binary_functor_t>(0);
33423 
33424  details::free_node(*(expr_gen.node_allocator_),branch[0]);
33425 
33426  expression_node_ptr result = error_node();
33427 
33428  const bool synthesis_result =
33429  synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
33430  (expr_gen, id(expr_gen, o0, o1, o2), c0, v0, c1, v1, result);
33431 
33432  if (synthesis_result)
33433  return result;
33434  else if (!expr_gen.valid_operator(o2,f2))
33435  return error_node();
33436 
33437  exprtk_debug(("((c0 o0 (v0 o1 c1)) o2 v1)\n"));
33438 
33439  return node_type::allocate(*(expr_gen.node_allocator_), c0, v0, c1, v1, f0, f1, f2);
33440  }
33441 
33442  static inline std::string id(expression_generator<Type>& expr_gen,
33443  const details::operator_type o0,
33444  const details::operator_type o1,
33445  const details::operator_type o2)
33446  {
33447  return (details::build_string() << "(t" << expr_gen.to_str(o0) << "(t" << expr_gen.to_str(o1) << "t)" << expr_gen.to_str(o2) << "t");
33448  }
33449  };
33450 
33452  {
33453  typedef typename vocovoc_t::type4 node_type;
33454  typedef typename vocovoc_t::sf4_type sf4_type;
33455  typedef typename node_type::T0 T0;
33456  typedef typename node_type::T1 T1;
33457  typedef typename node_type::T2 T2;
33458  typedef typename node_type::T3 T3;
33459 
33461  const details::operator_type& operation,
33462  expression_node_ptr (&branch)[2])
33463  {
33464  // ((v0 o0 (c0 o1 v1)) o2 c1)
33465  typedef typename synthesize_vocov_expression1::node_type lcl_vocov_t;
33466 
33467  const lcl_vocov_t* vocov = static_cast<const lcl_vocov_t*>(branch[0]);
33468  const Type& v0 = vocov->t0();
33469  const Type c0 = vocov->t1();
33470  const Type& v1 = vocov->t2();
33471  const Type c1 = static_cast<details::literal_node<Type>*>(branch[1])->value();
33472  const details::operator_type o0 = expr_gen.get_operator(vocov->f0());
33473  const details::operator_type o1 = expr_gen.get_operator(vocov->f1());
33474  const details::operator_type o2 = operation;
33475 
33476  binary_functor_t f0 = vocov->f0();
33477  binary_functor_t f1 = vocov->f1();
33478  binary_functor_t f2 = reinterpret_cast<binary_functor_t>(0);
33479 
33480  details::free_node(*(expr_gen.node_allocator_),branch[0]);
33481  details::free_node(*(expr_gen.node_allocator_),branch[1]);
33482 
33483  expression_node_ptr result = error_node();
33484 
33485  const bool synthesis_result =
33486  synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
33487  (expr_gen, id(expr_gen, o0, o1, o2), v0, c0, v1, c1, result);
33488 
33489  if (synthesis_result)
33490  return result;
33491  else if (!expr_gen.valid_operator(o2,f2))
33492  return error_node();
33493 
33494  exprtk_debug(("((v0 o0 (c0 o1 v1)) o2 c1)\n"));
33495 
33496  return node_type::allocate(*(expr_gen.node_allocator_), v0, c0, v1, c1, f0, f1, f2);
33497  }
33498 
33499  static inline std::string id(expression_generator<Type>& expr_gen,
33500  const details::operator_type o0,
33501  const details::operator_type o1,
33502  const details::operator_type o2)
33503  {
33504  return (details::build_string() << "(t" << expr_gen.to_str(o0) << "(t" << expr_gen.to_str(o1) << "t)" << expr_gen.to_str(o2) << "t");
33505  }
33506  };
33507 
33509  {
33510  typedef typename covovoc_t::type4 node_type;
33511  typedef typename covovoc_t::sf4_type sf4_type;
33512  typedef typename node_type::T0 T0;
33513  typedef typename node_type::T1 T1;
33514  typedef typename node_type::T2 T2;
33515  typedef typename node_type::T3 T3;
33516 
33518  const details::operator_type& operation,
33519  expression_node_ptr (&branch)[2])
33520  {
33521  // ((c0 o0 (v0 o1 v1)) o2 c1)
33522  typedef typename synthesize_covov_expression1::node_type lcl_covov_t;
33523 
33524  const lcl_covov_t* covov = static_cast<const lcl_covov_t*>(branch[0]);
33525  const Type c0 = covov->t0();
33526  const Type& v0 = covov->t1();
33527  const Type& v1 = covov->t2();
33528  const Type c1 = static_cast<details::literal_node<Type>*>(branch[1])->value();
33529  const details::operator_type o0 = expr_gen.get_operator(covov->f0());
33530  const details::operator_type o1 = expr_gen.get_operator(covov->f1());
33531  const details::operator_type o2 = operation;
33532 
33533  binary_functor_t f0 = covov->f0();
33534  binary_functor_t f1 = covov->f1();
33535  binary_functor_t f2 = reinterpret_cast<binary_functor_t>(0);
33536 
33537  details::free_node(*(expr_gen.node_allocator_),branch[0]);
33538  details::free_node(*(expr_gen.node_allocator_),branch[1]);
33539 
33540  expression_node_ptr result = error_node();
33541 
33542  const bool synthesis_result =
33543  synthesize_sf4ext_expression::template compile<T0, T1, T2, T3>
33544  (expr_gen, id(expr_gen, o0, o1, o2), c0, v0, v1, c1, result);
33545 
33546  if (synthesis_result)
33547  return result;
33548  else if (!expr_gen.valid_operator(o2,f2))
33549  return error_node();
33550 
33551  exprtk_debug(("((c0 o0 (v0 o1 v1)) o2 c1)\n"));
33552 
33553  return node_type::allocate(*(expr_gen.node_allocator_), c0, v0, v1, c1, f0, f1, f2);
33554  }
33555 
33556  static inline std::string id(expression_generator<Type>& expr_gen,
33557  const details::operator_type o0,
33558  const details::operator_type o1,
33559  const details::operator_type o2)
33560  {
33561  return (details::build_string() << "(t" << expr_gen.to_str(o0) << "(t" << expr_gen.to_str(o1) << "t)" << expr_gen.to_str(o2) << "t");
33562  }
33563  };
33564 
33566  {
33567  typedef typename vococov_t::type4 node_type;
33569  {
33570  // ((v0 o0 (c0 o1 c1)) o2 v1) - Not possible
33571  exprtk_debug(("((v0 o0 (c0 o1 c1)) o2 v1) - Not possible\n"));
33572  return error_node();
33573  }
33574 
33575  static inline std::string id(expression_generator<Type>&,
33577  {
33578  return "INVALID";
33579  }
33580  };
33581  #endif
33582 
33584  {
33585  // Definition: uv o uv
33586  details::operator_type o0 = static_cast<details::uv_base_node<Type>*>(branch[0])->operation();
33587  details::operator_type o1 = static_cast<details::uv_base_node<Type>*>(branch[1])->operation();
33588  const Type& v0 = static_cast<details::uv_base_node<Type>*>(branch[0])->v();
33589  const Type& v1 = static_cast<details::uv_base_node<Type>*>(branch[1])->v();
33590  unary_functor_t u0 = reinterpret_cast<unary_functor_t> (0);
33591  unary_functor_t u1 = reinterpret_cast<unary_functor_t> (0);
33592  binary_functor_t f = reinterpret_cast<binary_functor_t>(0);
33593 
33594  if (!valid_operator(o0,u0))
33595  return error_node();
33596  else if (!valid_operator(o1,u1))
33597  return error_node();
33598  else if (!valid_operator(operation,f))
33599  return error_node();
33600 
33601  expression_node_ptr result = error_node();
33602 
33603  if (
33604  (details::e_neg == o0) &&
33605  (details::e_neg == o1)
33606  )
33607  {
33608  switch (operation)
33609  {
33610  // (-v0 + -v1) --> -(v0 + v1)
33611  case details::e_add : result = (*this)(details::e_neg,
33612  node_allocator_->
33613  allocate_rr<typename details::
33615  exprtk_debug(("(-v0 + -v1) --> -(v0 + v1)\n"));
33616  break;
33617 
33618  // (-v0 - -v1) --> (v1 - v0)
33619  case details::e_sub : result = node_allocator_->
33620  allocate_rr<typename details::
33622  exprtk_debug(("(-v0 - -v1) --> (v1 - v0)\n"));
33623  break;
33624 
33625  // (-v0 * -v1) --> (v0 * v1)
33626  case details::e_mul : result = node_allocator_->
33627  allocate_rr<typename details::
33629  exprtk_debug(("(-v0 * -v1) --> (v0 * v1)\n"));
33630  break;
33631 
33632  // (-v0 / -v1) --> (v0 / v1)
33633  case details::e_div : result = node_allocator_->
33634  allocate_rr<typename details::
33636  exprtk_debug(("(-v0 / -v1) --> (v0 / v1)\n"));
33637  break;
33638 
33639  default : break;
33640  }
33641  }
33642 
33643  if (0 == result)
33644  {
33645  result = node_allocator_->
33646  allocate_rrrrr<typename details::uvouv_node<Type> >(v0, v1, u0, u1, f);
33647  }
33648 
33649  details::free_all_nodes(*node_allocator_,branch);
33650  return result;
33651  }
33652 
33653  #undef basic_opr_switch_statements
33654  #undef extended_opr_switch_statements
33655  #undef unary_opr_switch_statements
33656 
33657  #ifndef exprtk_disable_string_capabilities
33658 
33659  #define string_opr_switch_statements \
33660  case_stmt(details:: e_lt ,details:: lt_op) \
33661  case_stmt(details:: e_lte ,details:: lte_op) \
33662  case_stmt(details:: e_gt ,details:: gt_op) \
33663  case_stmt(details:: e_gte ,details:: gte_op) \
33664  case_stmt(details:: e_eq ,details:: eq_op) \
33665  case_stmt(details:: e_ne ,details:: ne_op) \
33666  case_stmt(details::e_in ,details:: in_op) \
33667  case_stmt(details::e_like ,details:: like_op) \
33668  case_stmt(details::e_ilike,details::ilike_op) \
33669 
33670  template <typename T0, typename T1>
33672  T0 s0, T1 s1,
33673  range_t rp0)
33674  {
33675  switch (opr)
33676  {
33677  #define case_stmt(op0,op1) \
33678  case op0 : return node_allocator_-> \
33679  allocate_ttt<typename details::str_xrox_node<Type,T0,T1,range_t,op1<Type> >,T0,T1> \
33680  (s0, s1, rp0); \
33681 
33683  #undef case_stmt
33684  default : return error_node();
33685  }
33686  }
33687 
33688  template <typename T0, typename T1>
33690  T0 s0, T1 s1,
33691  range_t rp1)
33692  {
33693  switch (opr)
33694  {
33695  #define case_stmt(op0,op1) \
33696  case op0 : return node_allocator_-> \
33697  allocate_ttt<typename details::str_xoxr_node<Type,T0,T1,range_t,op1<Type> >,T0,T1> \
33698  (s0, s1, rp1); \
33699 
33701  #undef case_stmt
33702  default : return error_node();
33703  }
33704  }
33705 
33706  template <typename T0, typename T1>
33708  T0 s0, T1 s1,
33709  range_t rp0, range_t rp1)
33710  {
33711  switch (opr)
33712  {
33713  #define case_stmt(op0,op1) \
33714  case op0 : return node_allocator_-> \
33715  allocate_tttt<typename details::str_xroxr_node<Type,T0,T1,range_t,op1<Type> >,T0,T1> \
33716  (s0, s1, rp0, rp1); \
33717 
33719  #undef case_stmt
33720  default : return error_node();
33721  }
33722  }
33723 
33724  template <typename T0, typename T1>
33726  {
33727  switch (opr)
33728  {
33729  #define case_stmt(op0,op1) \
33730  case op0 : return node_allocator_-> \
33731  allocate_tt<typename details::sos_node<Type,T0,T1,op1<Type> >,T0,T1>(s0, s1); \
33732 
33734  #undef case_stmt
33735  default : return error_node();
33736  }
33737  }
33738 
33740  {
33741  std::string& s0 = static_cast<details::stringvar_node<Type>*>(branch[0])->ref();
33742  std::string& s1 = static_cast<details::stringvar_node<Type>*>(branch[1])->ref();
33743 
33744  return synthesize_sos_expression_impl<std::string&,std::string&>(opr, s0, s1);
33745  }
33746 
33748  {
33749  std::string& s0 = static_cast<details::string_range_node<Type>*>(branch[0])->ref ();
33750  std::string& s1 = static_cast<details::stringvar_node<Type>*> (branch[1])->ref ();
33751  range_t rp0 = static_cast<details::string_range_node<Type>*>(branch[0])->range();
33752 
33753  static_cast<details::string_range_node<Type>*>(branch[0])->range_ref().clear();
33754 
33755  free_node(*node_allocator_,branch[0]);
33756 
33757  return synthesize_str_xrox_expression_impl<std::string&,std::string&>(opr, s0, s1, rp0);
33758  }
33759 
33761  {
33762  std::string& s0 = static_cast<details::stringvar_node<Type>*> (branch[0])->ref ();
33763  std::string& s1 = static_cast<details::string_range_node<Type>*>(branch[1])->ref ();
33764  range_t rp1 = static_cast<details::string_range_node<Type>*>(branch[1])->range();
33765 
33766  static_cast<details::string_range_node<Type>*>(branch[1])->range_ref().clear();
33767 
33768  free_node(*node_allocator_,branch[1]);
33769 
33770  return synthesize_str_xoxr_expression_impl<std::string&,std::string&>(opr, s0, s1, rp1);
33771  }
33772 
33774  {
33775  std::string& s0 = static_cast<details::stringvar_node<Type>*> (branch[0])->ref ();
33776  std::string s1 = static_cast<details::const_string_range_node<Type>*>(branch[1])->str ();
33777  range_t rp1 = static_cast<details::const_string_range_node<Type>*>(branch[1])->range();
33778 
33779  static_cast<details::const_string_range_node<Type>*>(branch[1])->range_ref().clear();
33780 
33781  free_node(*node_allocator_,branch[1]);
33782 
33783  return synthesize_str_xoxr_expression_impl<std::string&, const std::string>(opr, s0, s1, rp1);
33784  }
33785 
33787  {
33788  std::string& s0 = static_cast<details::string_range_node<Type>*>(branch[0])->ref ();
33789  std::string& s1 = static_cast<details::string_range_node<Type>*>(branch[1])->ref ();
33790  range_t rp0 = static_cast<details::string_range_node<Type>*>(branch[0])->range();
33791  range_t rp1 = static_cast<details::string_range_node<Type>*>(branch[1])->range();
33792 
33793  static_cast<details::string_range_node<Type>*>(branch[0])->range_ref().clear();
33794  static_cast<details::string_range_node<Type>*>(branch[1])->range_ref().clear();
33795 
33796  details::free_node(*node_allocator_,branch[0]);
33797  details::free_node(*node_allocator_,branch[1]);
33798 
33799  return synthesize_str_xroxr_expression_impl<std::string&,std::string&>(opr, s0, s1, rp0, rp1);
33800  }
33801 
33803  {
33804  std::string& s0 = static_cast< details::stringvar_node<Type>*>(branch[0])->ref();
33805  std::string s1 = static_cast<details::string_literal_node<Type>*>(branch[1])->str();
33806 
33807  details::free_node(*node_allocator_,branch[1]);
33808 
33809  return synthesize_sos_expression_impl<std::string&, const std::string>(opr, s0, s1);
33810  }
33811 
33813  {
33814  std::string s0 = static_cast<details::string_literal_node<Type>*>(branch[0])->str();
33815  std::string& s1 = static_cast< details::stringvar_node<Type>*>(branch[1])->ref();
33816 
33817  details::free_node(*node_allocator_,branch[0]);
33818 
33819  return synthesize_sos_expression_impl<const std::string,std::string&>(opr, s0, s1);
33820  }
33821 
33823  {
33824  std::string s0 = static_cast<details::string_literal_node<Type>*>(branch[0])->str ();
33825  std::string& s1 = static_cast<details::string_range_node<Type>*> (branch[1])->ref ();
33826  range_t rp1 = static_cast<details::string_range_node<Type>*> (branch[1])->range();
33827 
33828  static_cast<details::string_range_node<Type>*>(branch[1])->range_ref().clear();
33829 
33830  details::free_node(*node_allocator_,branch[0]);
33831  details::free_node(*node_allocator_,branch[1]);
33832 
33833  return synthesize_str_xoxr_expression_impl<const std::string,std::string&>(opr, s0, s1, rp1);
33834  }
33835 
33837  {
33838  std::string& s0 = static_cast<details::string_range_node<Type>*> (branch[0])->ref ();
33839  std::string s1 = static_cast<details::string_literal_node<Type>*>(branch[1])->str ();
33840  range_t rp0 = static_cast<details::string_range_node<Type>*> (branch[0])->range();
33841 
33842  static_cast<details::string_range_node<Type>*>(branch[0])->range_ref().clear();
33843 
33844  details::free_node(*node_allocator_,branch[0]);
33845  details::free_node(*node_allocator_,branch[1]);
33846 
33847  return synthesize_str_xrox_expression_impl<std::string&, const std::string>(opr, s0, s1, rp0);
33848  }
33849 
33851  {
33852  std::string& s0 = static_cast<details::string_range_node<Type>*> (branch[0])->ref ();
33853  std::string s1 = static_cast<details::const_string_range_node<Type>*>(branch[1])->str ();
33854  range_t rp0 = static_cast<details::string_range_node<Type>*> (branch[0])->range();
33855  range_t rp1 = static_cast<details::const_string_range_node<Type>*>(branch[1])->range();
33856 
33857  static_cast<details::string_range_node<Type>*> (branch[0])->range_ref().clear();
33858  static_cast<details::const_string_range_node<Type>*>(branch[1])->range_ref().clear();
33859 
33860  details::free_node(*node_allocator_,branch[0]);
33861  details::free_node(*node_allocator_,branch[1]);
33862 
33863  return synthesize_str_xroxr_expression_impl<std::string&, const std::string>(opr, s0, s1, rp0, rp1);
33864  }
33865 
33867  {
33868  const std::string s0 = static_cast<details::string_literal_node<Type>*>(branch[0])->str();
33869  const std::string s1 = static_cast<details::string_literal_node<Type>*>(branch[1])->str();
33870 
33871  expression_node_ptr result = error_node();
33872 
33873  if (details::e_add == opr)
33874  result = node_allocator_->allocate_c<details::string_literal_node<Type> >(s0 + s1);
33875  else if (details::e_in == opr)
33876  result = node_allocator_->allocate_c<details::literal_node<Type> >(details::in_op <Type>::process(s0,s1));
33877  else if (details::e_like == opr)
33878  result = node_allocator_->allocate_c<details::literal_node<Type> >(details::like_op <Type>::process(s0,s1));
33879  else if (details::e_ilike == opr)
33880  result = node_allocator_->allocate_c<details::literal_node<Type> >(details::ilike_op<Type>::process(s0,s1));
33881  else
33882  {
33883  expression_node_ptr temp = synthesize_sos_expression_impl<const std::string, const std::string>(opr, s0, s1);
33884 
33885  const Type v = temp->value();
33886 
33887  details::free_node(*node_allocator_,temp);
33888 
33889  result = node_allocator_->allocate<literal_node_t>(v);
33890  }
33891 
33892  details::free_all_nodes(*node_allocator_,branch);
33893 
33894  return result;
33895  }
33896 
33898  {
33899  const std::string s0 = static_cast<details::string_literal_node<Type>*> (branch[0])->str ();
33900  std::string s1 = static_cast<details::const_string_range_node<Type>*>(branch[1])->str ();
33901  range_t rp1 = static_cast<details::const_string_range_node<Type>*>(branch[1])->range();
33902 
33903  static_cast<details::const_string_range_node<Type>*>(branch[1])->range_ref().clear();
33904 
33905  free_node(*node_allocator_,branch[0]);
33906  free_node(*node_allocator_,branch[1]);
33907 
33908  return synthesize_str_xoxr_expression_impl<const std::string, const std::string>(opr, s0, s1, rp1);
33909  }
33910 
33912  {
33913  std::string s0 = static_cast<details::const_string_range_node<Type>*>(branch[0])->str ();
33914  std::string& s1 = static_cast<details::stringvar_node<Type>*> (branch[1])->ref ();
33915  range_t rp0 = static_cast<details::const_string_range_node<Type>*>(branch[0])->range();
33916 
33917  static_cast<details::const_string_range_node<Type>*>(branch[0])->range_ref().clear();
33918 
33919  free_node(*node_allocator_,branch[0]);
33920 
33921  return synthesize_str_xrox_expression_impl<const std::string,std::string&>(opr, s0, s1, rp0);
33922  }
33923 
33925  {
33926  const std::string s0 = static_cast<details::const_string_range_node<Type>*>(branch[0])->str ();
33927  std::string& s1 = static_cast<details::string_range_node<Type>*> (branch[1])->ref ();
33928  range_t rp0 = static_cast<details::const_string_range_node<Type>*>(branch[0])->range();
33929  range_t rp1 = static_cast<details::string_range_node<Type>*> (branch[1])->range();
33930 
33931  static_cast<details::const_string_range_node<Type>*>(branch[0])->range_ref().clear();
33932  static_cast<details::string_range_node<Type>*> (branch[1])->range_ref().clear();
33933 
33934  free_node(*node_allocator_,branch[0]);
33935  free_node(*node_allocator_,branch[1]);
33936 
33937  return synthesize_str_xroxr_expression_impl<const std::string,std::string&>(opr, s0, s1, rp0, rp1);
33938  }
33939 
33941  {
33942  std::string s0 = static_cast<details::const_string_range_node<Type>*>(branch[0])->str ();
33943  const std::string s1 = static_cast<details::string_literal_node<Type>*> (branch[1])->str ();
33944  range_t rp0 = static_cast<details::const_string_range_node<Type>*>(branch[0])->range();
33945 
33946  static_cast<details::const_string_range_node<Type>*>(branch[0])->range_ref().clear();
33947 
33948  details::free_all_nodes(*node_allocator_,branch);
33949 
33950  return synthesize_str_xrox_expression_impl<const std::string,std::string>(opr, s0, s1, rp0);
33951  }
33952 
33954  {
33955  std::string s0 = static_cast<details::const_string_range_node<Type>*>(branch[0])->str ();
33956  std::string s1 = static_cast<details::const_string_range_node<Type>*>(branch[1])->str ();
33957  range_t rp0 = static_cast<details::const_string_range_node<Type>*>(branch[0])->range();
33958  range_t rp1 = static_cast<details::const_string_range_node<Type>*>(branch[1])->range();
33959 
33960  static_cast<details::const_string_range_node<Type>*>(branch[0])->range_ref().clear();
33961  static_cast<details::const_string_range_node<Type>*>(branch[1])->range_ref().clear();
33962 
33963  details::free_all_nodes(*node_allocator_,branch);
33964 
33965  return synthesize_str_xroxr_expression_impl<const std::string, const std::string>(opr, s0, s1, rp0, rp1);
33966  }
33967 
33969  {
33970  switch (opr)
33971  {
33972  #define case_stmt(op0,op1) \
33973  case op0 : return node_allocator_-> \
33974  allocate_ttt<typename details::str_sogens_node<Type,op1<Type> > > \
33975  (opr, branch[0], branch[1]); \
33976 
33978  #undef case_stmt
33979  default : return error_node();
33980  }
33981  }
33982  #endif
33983 
33984  #ifndef exprtk_disable_string_capabilities
33986  {
33987  if ((0 == branch[0]) || (0 == branch[1]))
33988  {
33989  details::free_all_nodes(*node_allocator_,branch);
33990 
33991  return error_node();
33992  }
33993 
33994  const bool b0_is_s = details::is_string_node (branch[0]);
33995  const bool b0_is_cs = details::is_const_string_node (branch[0]);
33996  const bool b0_is_sr = details::is_string_range_node (branch[0]);
33997  const bool b0_is_csr = details::is_const_string_range_node(branch[0]);
33998 
33999  const bool b1_is_s = details::is_string_node (branch[1]);
34000  const bool b1_is_cs = details::is_const_string_node (branch[1]);
34001  const bool b1_is_sr = details::is_string_range_node (branch[1]);
34002  const bool b1_is_csr = details::is_const_string_range_node(branch[1]);
34003 
34004  const bool b0_is_gen = details::is_string_assignment_node (branch[0]) ||
34006  details::is_string_concat_node (branch[0]) ||
34007  details::is_string_function_node (branch[0]) ||
34008  details::is_string_condition_node (branch[0]) ||
34009  details::is_string_ccondition_node (branch[0]) ||
34010  details::is_string_vararg_node (branch[0]) ;
34011 
34012  const bool b1_is_gen = details::is_string_assignment_node (branch[1]) ||
34014  details::is_string_concat_node (branch[1]) ||
34015  details::is_string_function_node (branch[1]) ||
34016  details::is_string_condition_node (branch[1]) ||
34017  details::is_string_ccondition_node (branch[1]) ||
34018  details::is_string_vararg_node (branch[1]) ;
34019 
34020  if (details::e_add == opr)
34021  {
34022  if (!b0_is_cs || !b1_is_cs)
34023  {
34024  return synthesize_expression<string_concat_node_t,2>(opr,branch);
34025  }
34026  }
34027 
34028  if (b0_is_gen || b1_is_gen)
34029  {
34030  return synthesize_strogen_expression(opr,branch);
34031  }
34032  else if (b0_is_s)
34033  {
34034  if (b1_is_s ) return synthesize_sos_expression (opr,branch);
34035  else if (b1_is_cs ) return synthesize_socs_expression (opr,branch);
34036  else if (b1_is_sr ) return synthesize_sosr_expression (opr,branch);
34037  else if (b1_is_csr) return synthesize_socsr_expression (opr,branch);
34038  }
34039  else if (b0_is_cs)
34040  {
34041  if (b1_is_s ) return synthesize_csos_expression (opr,branch);
34042  else if (b1_is_cs ) return synthesize_csocs_expression (opr,branch);
34043  else if (b1_is_sr ) return synthesize_csosr_expression (opr,branch);
34044  else if (b1_is_csr) return synthesize_csocsr_expression(opr,branch);
34045  }
34046  else if (b0_is_sr)
34047  {
34048  if (b1_is_s ) return synthesize_sros_expression (opr,branch);
34049  else if (b1_is_sr ) return synthesize_srosr_expression (opr,branch);
34050  else if (b1_is_cs ) return synthesize_srocs_expression (opr,branch);
34051  else if (b1_is_csr) return synthesize_srocsr_expression(opr,branch);
34052  }
34053  else if (b0_is_csr)
34054  {
34055  if (b1_is_s ) return synthesize_csros_expression (opr,branch);
34056  else if (b1_is_sr ) return synthesize_csrosr_expression (opr,branch);
34057  else if (b1_is_cs ) return synthesize_csrocs_expression (opr,branch);
34058  else if (b1_is_csr) return synthesize_csrocsr_expression(opr,branch);
34059  }
34060 
34061  return error_node();
34062  }
34063  #else
34064  inline expression_node_ptr synthesize_string_expression(const details::operator_type&, expression_node_ptr (&branch)[2])
34065  {
34066  details::free_all_nodes(*node_allocator_,branch);
34067  return error_node();
34068  }
34069  #endif
34070 
34071  #ifndef exprtk_disable_string_capabilities
34073  {
34074  if (details::e_inrange != opr)
34075  return error_node();
34076  else if ((0 == branch[0]) || (0 == branch[1]) || (0 == branch[2]))
34077  {
34078  details::free_all_nodes(*node_allocator_,branch);
34079 
34080  return error_node();
34081  }
34082  else if (
34083  details::is_const_string_node(branch[0]) &&
34084  details::is_const_string_node(branch[1]) &&
34086  )
34087  {
34088  const std::string s0 = static_cast<details::string_literal_node<Type>*>(branch[0])->str();
34089  const std::string s1 = static_cast<details::string_literal_node<Type>*>(branch[1])->str();
34090  const std::string s2 = static_cast<details::string_literal_node<Type>*>(branch[2])->str();
34091 
34092  const Type v = (((s0 <= s1) && (s1 <= s2)) ? Type(1) : Type(0));
34093 
34094  details::free_all_nodes(*node_allocator_,branch);
34095 
34096  return node_allocator_->allocate_c<details::literal_node<Type> >(v);
34097  }
34098  else if (
34099  details::is_string_node(branch[0]) &&
34100  details::is_string_node(branch[1]) &&
34101  details::is_string_node(branch[2])
34102  )
34103  {
34104  std::string& s0 = static_cast<details::stringvar_node<Type>*>(branch[0])->ref();
34105  std::string& s1 = static_cast<details::stringvar_node<Type>*>(branch[1])->ref();
34106  std::string& s2 = static_cast<details::stringvar_node<Type>*>(branch[2])->ref();
34107 
34109 
34110  return node_allocator_->allocate_type<inrange_t,std::string&,std::string&,std::string&>(s0,s1,s2);
34111  }
34112  else if (
34113  details::is_const_string_node(branch[0]) &&
34114  details::is_string_node(branch[1]) &&
34116  )
34117  {
34118  std::string s0 = static_cast<details::string_literal_node<Type>*>(branch[0])->str();
34119  std::string& s1 = static_cast< details::stringvar_node<Type>*>(branch[1])->ref();
34120  std::string s2 = static_cast<details::string_literal_node<Type>*>(branch[2])->str();
34121 
34123 
34124  details::free_node(*node_allocator_,branch[0]);
34125  details::free_node(*node_allocator_,branch[2]);
34126 
34127  return node_allocator_->allocate_type<inrange_t,std::string,std::string&,std::string>(s0,s1,s2);
34128  }
34129  else if (
34130  details::is_string_node(branch[0]) &&
34131  details::is_const_string_node(branch[1]) &&
34132  details::is_string_node(branch[2])
34133  )
34134  {
34135  std::string& s0 = static_cast< details::stringvar_node<Type>*>(branch[0])->ref();
34136  std::string s1 = static_cast<details::string_literal_node<Type>*>(branch[1])->str();
34137  std::string& s2 = static_cast< details::stringvar_node<Type>*>(branch[2])->ref();
34138 
34140 
34141  details::free_node(*node_allocator_,branch[1]);
34142 
34143  return node_allocator_->allocate_type<inrange_t,std::string&,std::string,std::string&>(s0,s1,s2);
34144  }
34145  else if (
34146  details::is_string_node(branch[0]) &&
34147  details::is_string_node(branch[1]) &&
34149  )
34150  {
34151  std::string& s0 = static_cast< details::stringvar_node<Type>*>(branch[0])->ref();
34152  std::string& s1 = static_cast< details::stringvar_node<Type>*>(branch[1])->ref();
34153  std::string s2 = static_cast<details::string_literal_node<Type>*>(branch[2])->str();
34154 
34156 
34157  details::free_node(*node_allocator_,branch[2]);
34158 
34159  return node_allocator_->allocate_type<inrange_t,std::string&,std::string&,std::string>(s0,s1,s2);
34160  }
34161  else if (
34162  details::is_const_string_node(branch[0]) &&
34163  details:: is_string_node(branch[1]) &&
34164  details:: is_string_node(branch[2])
34165  )
34166  {
34167  std::string s0 = static_cast<details::string_literal_node<Type>*>(branch[0])->str();
34168  std::string& s1 = static_cast< details::stringvar_node<Type>*>(branch[1])->ref();
34169  std::string& s2 = static_cast< details::stringvar_node<Type>*>(branch[2])->ref();
34170 
34172 
34173  details::free_node(*node_allocator_,branch[0]);
34174 
34175  return node_allocator_->allocate_type<inrange_t,std::string,std::string&,std::string&>(s0,s1,s2);
34176  }
34177  else
34178  return error_node();
34179  }
34180  #else
34181  inline expression_node_ptr synthesize_string_expression(const details::operator_type&, expression_node_ptr (&branch)[3])
34182  {
34183  details::free_all_nodes(*node_allocator_,branch);
34184  return error_node();
34185  }
34186  #endif
34187 
34189  {
34190  /*
34191  Note: The following are the type promotion rules
34192  that relate to operations that include 'null':
34193  0. null ==/!= null --> true false
34194  1. null operation null --> null
34195  2. x ==/!= null --> true/false
34196  3. null ==/!= x --> true/false
34197  4. x operation null --> x
34198  5. null operation x --> x
34199  */
34200 
34201  typedef typename details::null_eq_node<T> nulleq_node_t;
34202 
34203  bool b0_null = details::is_null_node(branch[0]);
34204  bool b1_null = details::is_null_node(branch[1]);
34205 
34206  if (b0_null && b1_null)
34207  {
34208  expression_node_ptr result = error_node();
34209 
34210  if (details::e_eq == operation)
34211  result = node_allocator_->allocate_c<literal_node_t>(T(1));
34212  else if (details::e_ne == operation)
34213  result = node_allocator_->allocate_c<literal_node_t>(T(0));
34214 
34215  if (result)
34216  {
34217  details::free_node(*node_allocator_,branch[0]);
34218  details::free_node(*node_allocator_,branch[1]);
34219 
34220  return result;
34221  }
34222 
34223  details::free_node(*node_allocator_,branch[1]);
34224 
34225  return branch[0];
34226  }
34227  else if (details::e_eq == operation)
34228  {
34229  expression_node_ptr result = node_allocator_->
34230  allocate_rc<nulleq_node_t>(branch[b0_null ? 0 : 1],true);
34231 
34232  details::free_node(*node_allocator_,branch[b0_null ? 1 : 0]);
34233 
34234  return result;
34235  }
34236  else if (details::e_ne == operation)
34237  {
34238  expression_node_ptr result = node_allocator_->
34239  allocate_rc<nulleq_node_t>(branch[b0_null ? 0 : 1],false);
34240 
34241  details::free_node(*node_allocator_,branch[b0_null ? 1 : 0]);
34242 
34243  return result;
34244  }
34245  else if (b0_null)
34246  {
34247  details::free_node(*node_allocator_,branch[0]);
34248  branch[0] = branch[1];
34249  branch[1] = error_node();
34250  }
34251  else if (b1_null)
34252  {
34253  details::free_node(*node_allocator_,branch[1]);
34254  branch[1] = error_node();
34255  }
34256 
34257  if (
34258  (details::e_add == operation) || (details::e_sub == operation) ||
34259  (details::e_mul == operation) || (details::e_div == operation) ||
34260  (details::e_mod == operation) || (details::e_pow == operation)
34261  )
34262  {
34263  return branch[0];
34264  }
34265  else if (
34266  (details::e_lt == operation) || (details::e_lte == operation) ||
34267  (details::e_gt == operation) || (details::e_gte == operation) ||
34268  (details::e_and == operation) || (details::e_nand == operation) ||
34269  (details::e_or == operation) || (details::e_nor == operation) ||
34270  (details::e_xor == operation) || (details::e_xnor == operation) ||
34271  (details::e_in == operation) || (details::e_like == operation) ||
34272  (details::e_ilike == operation)
34273  )
34274  {
34275  return node_allocator_->allocate_c<literal_node_t>(T(0));
34276  }
34277 
34278  details::free_node(*node_allocator_,branch[0]);
34279 
34280  return node_allocator_->allocate<details::null_node<Type> >();
34281  }
34282 
34283  template <typename NodeType, std::size_t N>
34285  {
34286  if (
34287  (details::e_in == operation) ||
34288  (details::e_like == operation) ||
34289  (details::e_ilike == operation)
34290  )
34291  {
34292  free_all_nodes(*node_allocator_,branch);
34293 
34294  return error_node();
34295  }
34296  else if (!details::all_nodes_valid<N>(branch))
34297  {
34298  free_all_nodes(*node_allocator_,branch);
34299 
34300  return error_node();
34301  }
34302  else if ((details::e_default != operation))
34303  {
34304  // Attempt simple constant folding optimisation.
34305  expression_node_ptr expression_point = node_allocator_->allocate<NodeType>(operation,branch);
34306 
34307  if (is_constant_foldable<N>(branch))
34308  {
34309  Type v = expression_point->value();
34310  details::free_node(*node_allocator_,expression_point);
34311 
34312  return node_allocator_->allocate<literal_node_t>(v);
34313  }
34314  else
34315  return expression_point;
34316  }
34317  else
34318  return error_node();
34319  }
34320 
34321  template <typename NodeType, std::size_t N>
34323  {
34324  if (!details::all_nodes_valid<N>(branch))
34325  {
34326  free_all_nodes(*node_allocator_,branch);
34327 
34328  return error_node();
34329  }
34330 
34331  typedef typename details::function_N_node<T,ifunction_t,N> function_N_node_t;
34332 
34333  // Attempt simple constant folding optimisation.
34334 
34335  expression_node_ptr expression_point = node_allocator_->allocate<NodeType>(f);
34336  function_N_node_t* func_node_ptr = dynamic_cast<function_N_node_t*>(expression_point);
34337 
34338  if (0 == func_node_ptr)
34339  {
34340  free_all_nodes(*node_allocator_,branch);
34341 
34342  return error_node();
34343  }
34344  else
34345  func_node_ptr->init_branches(branch);
34346 
34347  if (is_constant_foldable<N>(branch) && !f->has_side_effects())
34348  {
34349  Type v = expression_point->value();
34350  details::free_node(*node_allocator_,expression_point);
34351 
34352  return node_allocator_->allocate<literal_node_t>(v);
34353  }
34354 
34355  parser_->state_.activate_side_effect("synthesize_expression(function<NT,N>)");
34356 
34357  return expression_point;
34358  }
34359 
34369  };
34370 
34371  inline void set_error(const parser_error::type& error_type)
34372  {
34373  error_list_.push_back(error_type);
34374  }
34375 
34376  inline void remove_last_error()
34377  {
34378  if (!error_list_.empty())
34379  {
34380  error_list_.pop_back();
34381  }
34382  }
34383 
34384  inline void set_synthesis_error(const std::string& synthesis_error_message)
34385  {
34386  if (synthesis_error_.empty())
34387  {
34388  synthesis_error_ = synthesis_error_message;
34389  }
34390  }
34391 
34393  {
34394  for (std::size_t i = 0; i < sem_.size(); ++i)
34395  {
34396  scope_element& se = sem_.get_element(i);
34397 
34398  if (
34399  (scope_element::e_variable == se.type) ||
34400  (scope_element::e_vecelem == se.type)
34401  )
34402  {
34403  if (se.var_node)
34404  {
34406  }
34407 
34408  if (se.data)
34409  {
34410  e.register_local_data(se.data, 1, 0);
34411  }
34412  }
34413  else if (scope_element::e_vector == se.type)
34414  {
34415  if (se.vec_node)
34416  {
34418  }
34419 
34420  if (se.data)
34421  {
34422  e.register_local_data(se.data, se.size, 1);
34423  }
34424  }
34425  #ifndef exprtk_disable_string_capabilities
34426  else if (scope_element::e_string == se.type)
34427  {
34428  if (se.str_node)
34429  {
34431  }
34432 
34433  if (se.data)
34434  {
34435  e.register_local_data(se.data, se.size, 2);
34436  }
34437  }
34438  #endif
34439 
34440  se.var_node = 0;
34441  se.vec_node = 0;
34442  #ifndef exprtk_disable_string_capabilities
34443  se.str_node = 0;
34444  #endif
34445  se.data = 0;
34446  se.ref_count = 0;
34447  se.active = false;
34448  }
34449  }
34450 
34452  {
34453  e.register_return_results(results_context_);
34454  results_context_ = 0;
34455  }
34456 
34458  {
34459  #define register_unary_op(Op,UnaryFunctor) \
34460  m.insert(std::make_pair(Op,UnaryFunctor<T>::process)); \
34461 
34462  register_unary_op(details:: e_abs, details:: abs_op)
34463  register_unary_op(details:: e_acos, details:: acos_op)
34464  register_unary_op(details::e_acosh, details::acosh_op)
34465  register_unary_op(details:: e_asin, details:: asin_op)
34466  register_unary_op(details::e_asinh, details::asinh_op)
34467  register_unary_op(details::e_atanh, details::atanh_op)
34468  register_unary_op(details:: e_ceil, details:: ceil_op)
34469  register_unary_op(details:: e_cos, details:: cos_op)
34470  register_unary_op(details:: e_cosh, details:: cosh_op)
34471  register_unary_op(details:: e_exp, details:: exp_op)
34472  register_unary_op(details::e_expm1, details::expm1_op)
34473  register_unary_op(details::e_floor, details::floor_op)
34474  register_unary_op(details:: e_log, details:: log_op)
34475  register_unary_op(details::e_log10, details::log10_op)
34476  register_unary_op(details:: e_log2, details:: log2_op)
34477  register_unary_op(details::e_log1p, details::log1p_op)
34478  register_unary_op(details:: e_neg, details:: neg_op)
34479  register_unary_op(details:: e_pos, details:: pos_op)
34480  register_unary_op(details::e_round, details::round_op)
34481  register_unary_op(details:: e_sin, details:: sin_op)
34482  register_unary_op(details:: e_sinc, details:: sinc_op)
34483  register_unary_op(details:: e_sinh, details:: sinh_op)
34484  register_unary_op(details:: e_sqrt, details:: sqrt_op)
34485  register_unary_op(details:: e_tan, details:: tan_op)
34486  register_unary_op(details:: e_tanh, details:: tanh_op)
34487  register_unary_op(details:: e_cot, details:: cot_op)
34488  register_unary_op(details:: e_sec, details:: sec_op)
34489  register_unary_op(details:: e_csc, details:: csc_op)
34490  register_unary_op(details:: e_r2d, details:: r2d_op)
34491  register_unary_op(details:: e_d2r, details:: d2r_op)
34492  register_unary_op(details:: e_d2g, details:: d2g_op)
34493  register_unary_op(details:: e_g2d, details:: g2d_op)
34494  register_unary_op(details:: e_notl, details:: notl_op)
34495  register_unary_op(details:: e_sgn, details:: sgn_op)
34496  register_unary_op(details:: e_erf, details:: erf_op)
34497  register_unary_op(details:: e_erfc, details:: erfc_op)
34498  register_unary_op(details:: e_ncdf, details:: ncdf_op)
34499  register_unary_op(details:: e_frac, details:: frac_op)
34500  register_unary_op(details::e_trunc, details::trunc_op)
34501  #undef register_unary_op
34502  }
34503 
34505  {
34506  typedef typename binary_op_map_t::value_type value_type;
34507 
34508  #define register_binary_op(Op,BinaryFunctor) \
34509  m.insert(value_type(Op,BinaryFunctor<T>::process)); \
34510 
34529  #undef register_binary_op
34530  }
34531 
34533  {
34534  typedef typename inv_binary_op_map_t::value_type value_type;
34535 
34536  #define register_binary_op(Op,BinaryFunctor) \
34537  m.insert(value_type(BinaryFunctor<T>::process,Op)); \
34538 
34557  #undef register_binary_op
34558  }
34559 
34560  inline void load_sf3_map(sf3_map_t& sf3_map)
34561  {
34562  typedef std::pair<trinary_functor_t,details::operator_type> pair_t;
34563 
34564  #define register_sf3(Op) \
34565  sf3_map[details::sf##Op##_op<T>::id()] = pair_t(details::sf##Op##_op<T>::process,details::e_sf##Op); \
34566 
34575  #undef register_sf3
34576 
34577  #define register_sf3_extid(Id, Op) \
34578  sf3_map[Id] = pair_t(details::sf##Op##_op<T>::process,details::e_sf##Op); \
34579 
34580  register_sf3_extid("(t-t)-t",23) // (t-t)-t --> t-(t+t)
34581  #undef register_sf3_extid
34582  }
34583 
34584  inline void load_sf4_map(sf4_map_t& sf4_map)
34585  {
34586  typedef std::pair<quaternary_functor_t,details::operator_type> pair_t;
34587 
34588  #define register_sf4(Op) \
34589  sf4_map[details::sf##Op##_op<T>::id()] = pair_t(details::sf##Op##_op<T>::process,details::e_sf##Op); \
34590 
34600  #undef register_sf4
34601 
34602  #define register_sf4ext(Op) \
34603  sf4_map[details::sfext##Op##_op<T>::id()] = pair_t(details::sfext##Op##_op<T>::process,details::e_sf4ext##Op); \
34604 
34621  #undef register_sf4ext
34622  }
34623 
34625  {
34626  if (0 == results_context_)
34627  {
34628  results_context_ = new results_context_t();
34629  }
34630 
34631  return (*results_context_);
34632  }
34633 
34634  inline void return_cleanup()
34635  {
34636  #ifndef exprtk_disable_return_statement
34637  if (results_context_)
34638  {
34639  delete results_context_;
34640  results_context_ = 0;
34641  }
34642 
34643  state_.return_stmt_present = false;
34644  #endif
34645  }
34646 
34647  private:
34648 
34649  parser(const parser<T>&);
34650  parser<T>& operator=(const parser<T>&);
34651 
34657  std::deque<parser_error::type> error_list_;
34658  std::deque<bool> brkcnt_list_;
34670  std::string synthesis_error_;
34672 
34674 
34682 
34683  template <typename ParserType>
34684  friend void details::disable_type_checking(ParserType& p);
34685  };
34686 
34687  template <typename Allocator,
34688  template <typename, typename> class Sequence>
34689  inline bool collect_variables(const std::string& expr_str,
34690  Sequence<std::string, Allocator>& symbol_list)
34691  {
34692  typedef double T;
34693  typedef exprtk::symbol_table<T> symbol_table_t;
34694  typedef exprtk::expression<T> expression_t;
34695  typedef exprtk::parser<T> parser_t;
34696  typedef parser_t::dependent_entity_collector::symbol_t symbol_t;
34697 
34698  symbol_table_t symbol_table;
34699  expression_t expression;
34700  parser_t parser;
34701 
34702  expression.register_symbol_table(symbol_table);
34703 
34704  parser.enable_unknown_symbol_resolver();
34705  parser.dec().collect_variables() = true;
34706 
34707  if (!parser.compile(expr_str, expression))
34708  return false;
34709 
34710  std::deque<symbol_t> symb_list;
34711 
34712  parser.dec().symbols(symb_list);
34713 
34714  for (std::size_t i = 0; i < symb_list.size(); ++i)
34715  {
34716  symbol_list.push_back(symb_list[i].first);
34717  }
34718 
34719  return true;
34720  }
34721 
34722  template <typename T,
34723  typename Allocator,
34724  template <typename, typename> class Sequence>
34725  inline bool collect_variables(const std::string& expr_str,
34726  exprtk::symbol_table<T>& extrnl_symbol_table,
34727  Sequence<std::string, Allocator>& symbol_list)
34728  {
34729  typedef exprtk::symbol_table<T> symbol_table_t;
34730  typedef exprtk::expression<T> expression_t;
34731  typedef exprtk::parser<T> parser_t;
34732  typedef typename parser_t::dependent_entity_collector::symbol_t symbol_t;
34733 
34734  symbol_table_t symbol_table;
34735  expression_t expression;
34736  parser_t parser;
34737 
34738  expression.register_symbol_table(symbol_table);
34739  expression.register_symbol_table(extrnl_symbol_table);
34740 
34741  parser.enable_unknown_symbol_resolver();
34742  parser.dec().collect_variables() = true;
34743 
34745 
34746  if (!parser.compile(expr_str, expression))
34747  return false;
34748 
34749  std::deque<symbol_t> symb_list;
34750 
34751  parser.dec().symbols(symb_list);
34752 
34753  for (std::size_t i = 0; i < symb_list.size(); ++i)
34754  {
34755  symbol_list.push_back(symb_list[i].first);
34756  }
34757 
34758  return true;
34759  }
34760 
34761  template <typename Allocator,
34762  template <typename, typename> class Sequence>
34763  inline bool collect_functions(const std::string& expr_str,
34764  Sequence<std::string, Allocator>& symbol_list)
34765  {
34766  typedef double T;
34767  typedef exprtk::symbol_table<T> symbol_table_t;
34768  typedef exprtk::expression<T> expression_t;
34769  typedef exprtk::parser<T> parser_t;
34770  typedef parser_t::dependent_entity_collector::symbol_t symbol_t;
34771 
34772  symbol_table_t symbol_table;
34773  expression_t expression;
34774  parser_t parser;
34775 
34776  expression.register_symbol_table(symbol_table);
34777 
34778  parser.enable_unknown_symbol_resolver();
34779  parser.dec().collect_functions() = true;
34780 
34781  if (!parser.compile(expr_str, expression))
34782  return false;
34783 
34784  std::deque<symbol_t> symb_list;
34785 
34786  parser.dec().symbols(symb_list);
34787 
34788  for (std::size_t i = 0; i < symb_list.size(); ++i)
34789  {
34790  symbol_list.push_back(symb_list[i].first);
34791  }
34792 
34793  return true;
34794  }
34795 
34796  template <typename T,
34797  typename Allocator,
34798  template <typename, typename> class Sequence>
34799  inline bool collect_functions(const std::string& expr_str,
34800  exprtk::symbol_table<T>& extrnl_symbol_table,
34801  Sequence<std::string, Allocator>& symbol_list)
34802  {
34803  typedef exprtk::symbol_table<T> symbol_table_t;
34804  typedef exprtk::expression<T> expression_t;
34805  typedef exprtk::parser<T> parser_t;
34806  typedef typename parser_t::dependent_entity_collector::symbol_t symbol_t;
34807 
34808  symbol_table_t symbol_table;
34809  expression_t expression;
34810  parser_t parser;
34811 
34812  expression.register_symbol_table(symbol_table);
34813  expression.register_symbol_table(extrnl_symbol_table);
34814 
34815  parser.enable_unknown_symbol_resolver();
34816  parser.dec().collect_functions() = true;
34817 
34819 
34820  if (!parser.compile(expr_str, expression))
34821  return false;
34822 
34823  std::deque<symbol_t> symb_list;
34824 
34825  parser.dec().symbols(symb_list);
34826 
34827  for (std::size_t i = 0; i < symb_list.size(); ++i)
34828  {
34829  symbol_list.push_back(symb_list[i].first);
34830  }
34831 
34832  return true;
34833  }
34834 
34835  template <typename T>
34836  inline T integrate(const expression<T>& e,
34837  T& x,
34838  const T& r0, const T& r1,
34839  const std::size_t number_of_intervals = 1000000)
34840  {
34841  if (r0 > r1)
34842  return T(0);
34843 
34844  const T h = (r1 - r0) / (T(2) * number_of_intervals);
34845  T total_area = T(0);
34846 
34847  for (std::size_t i = 0; i < number_of_intervals; ++i)
34848  {
34849  x = r0 + T(2) * i * h;
34850  const T y0 = e.value(); x += h;
34851  const T y1 = e.value(); x += h;
34852  const T y2 = e.value(); x += h;
34853  total_area += h * (y0 + T(4) * y1 + y2) / T(3);
34854  }
34855 
34856  return total_area;
34857  }
34858 
34859  template <typename T>
34860  inline T integrate(const expression<T>& e,
34861  const std::string& variable_name,
34862  const T& r0, const T& r1,
34863  const std::size_t number_of_intervals = 1000000)
34864  {
34865  const symbol_table<T>& sym_table = e.get_symbol_table();
34866 
34867  if (!sym_table.valid())
34868  return std::numeric_limits<T>::quiet_NaN();
34869 
34870  details::variable_node<T>* var = sym_table.get_variable(variable_name);
34871 
34872  if (var)
34873  {
34874  T& x = var->ref();
34875  T x_original = x;
34876  T result = integrate(e,x,r0,r1,number_of_intervals);
34877  x = x_original;
34878 
34879  return result;
34880  }
34881  else
34882  return std::numeric_limits<T>::quiet_NaN();
34883  }
34884 
34885  template <typename T>
34886  inline T derivative(const expression<T>& e,
34887  T& x,
34888  const T& h = T(0.00000001))
34889  {
34890  const T x_init = x;
34891  const T _2h = T(2) * h;
34892 
34893  x = x_init + _2h;
34894  const T y0 = e.value();
34895  x = x_init + h;
34896  const T y1 = e.value();
34897  x = x_init - h;
34898  const T y2 = e.value();
34899  x = x_init - _2h;
34900  const T y3 = e.value();
34901  x = x_init;
34902 
34903  return (-y0 + T(8) * (y1 - y2) + y3) / (T(12) * h);
34904  }
34905 
34906  template <typename T>
34908  T& x,
34909  const T& h = T(0.00001))
34910  {
34911  const T x_init = x;
34912  const T _2h = T(2) * h;
34913 
34914  const T y = e.value();
34915  x = x_init + _2h;
34916  const T y0 = e.value();
34917  x = x_init + h;
34918  const T y1 = e.value();
34919  x = x_init - h;
34920  const T y2 = e.value();
34921  x = x_init - _2h;
34922  const T y3 = e.value();
34923  x = x_init;
34924 
34925  return (-y0 + T(16) * (y1 + y2) - T(30) * y - y3) / (T(12) * h * h);
34926  }
34927 
34928  template <typename T>
34929  inline T third_derivative(const expression<T>& e,
34930  T& x,
34931  const T& h = T(0.0001))
34932  {
34933  const T x_init = x;
34934  const T _2h = T(2) * h;
34935 
34936  x = x_init + _2h;
34937  const T y0 = e.value();
34938  x = x_init + h;
34939  const T y1 = e.value();
34940  x = x_init - h;
34941  const T y2 = e.value();
34942  x = x_init - _2h;
34943  const T y3 = e.value();
34944  x = x_init;
34945 
34946  return (y0 + T(2) * (y2 - y1) - y3) / (T(2) * h * h * h);
34947  }
34948 
34949  template <typename T>
34950  inline T derivative(const expression<T>& e,
34951  const std::string& variable_name,
34952  const T& h = T(0.00000001))
34953  {
34954  const symbol_table<T>& sym_table = e.get_symbol_table();
34955 
34956  if (!sym_table.valid())
34957  {
34958  return std::numeric_limits<T>::quiet_NaN();
34959  }
34960 
34961  details::variable_node<T>* var = sym_table.get_variable(variable_name);
34962 
34963  if (var)
34964  {
34965  T& x = var->ref();
34966  T x_original = x;
34967  T result = derivative(e,x,h);
34968  x = x_original;
34969 
34970  return result;
34971  }
34972  else
34973  return std::numeric_limits<T>::quiet_NaN();
34974  }
34975 
34976  template <typename T>
34978  const std::string& variable_name,
34979  const T& h = T(0.00001))
34980  {
34981  const symbol_table<T>& sym_table = e.get_symbol_table();
34982 
34983  if (!sym_table.valid())
34984  {
34985  return std::numeric_limits<T>::quiet_NaN();
34986  }
34987 
34988  details::variable_node<T>* var = sym_table.get_variable(variable_name);
34989 
34990  if (var)
34991  {
34992  T& x = var->ref();
34993  const T x_original = x;
34994  const T result = second_derivative(e,x,h);
34995  x = x_original;
34996 
34997  return result;
34998  }
34999  else
35000  return std::numeric_limits<T>::quiet_NaN();
35001  }
35002 
35003  template <typename T>
35004  inline T third_derivative(const expression<T>& e,
35005  const std::string& variable_name,
35006  const T& h = T(0.0001))
35007  {
35008  const symbol_table<T>& sym_table = e.get_symbol_table();
35009 
35010  if (!sym_table.valid())
35011  {
35012  return std::numeric_limits<T>::quiet_NaN();
35013  }
35014 
35015  details::variable_node<T>* var = sym_table.get_variable(variable_name);
35016 
35017  if (var)
35018  {
35019  T& x = var->ref();
35020  const T x_original = x;
35021  const T result = third_derivative(e,x,h);
35022  x = x_original;
35023 
35024  return result;
35025  }
35026  else
35027  return std::numeric_limits<T>::quiet_NaN();
35028  }
35029 
35030  /*
35031  Note: The following 'compute' routines are simple helpers,
35032  for quickly setting up the required pieces of code in order
35033  to evaluate an expression. By virtue of how they operate
35034  there will be an overhead with regards to their setup and
35035  teardown and hence should not be used in time critical
35036  sections of code.
35037  Furthermore they only assume a small sub set of variables,
35038  no string variables or user defined functions.
35039  */
35040  template <typename T>
35041  inline bool compute(const std::string& expression_string, T& result)
35042  {
35043  // No variables
35044  symbol_table<T> symbol_table;
35045  symbol_table.add_constants();
35046 
35048  expression.register_symbol_table(symbol_table);
35049 
35050  parser<T> parser;
35051 
35052  if (parser.compile(expression_string,expression))
35053  {
35054  result = expression.value();
35055 
35056  return true;
35057  }
35058  else
35059  return false;
35060  }
35061 
35062  template <typename T>
35063  inline bool compute(const std::string& expression_string,
35064  const T& x,
35065  T& result)
35066  {
35067  // Only 'x'
35068  static const std::string x_var("x");
35069 
35070  symbol_table<T> symbol_table;
35071  symbol_table.add_constants();
35072  symbol_table.add_constant(x_var,x);
35073 
35075  expression.register_symbol_table(symbol_table);
35076 
35077  parser<T> parser;
35078 
35079  if (parser.compile(expression_string,expression))
35080  {
35081  result = expression.value();
35082 
35083  return true;
35084  }
35085  else
35086  return false;
35087  }
35088 
35089  template <typename T>
35090  inline bool compute(const std::string& expression_string,
35091  const T&x, const T& y,
35092  T& result)
35093  {
35094  // Only 'x' and 'y'
35095  static const std::string x_var("x");
35096  static const std::string y_var("y");
35097 
35098  symbol_table<T> symbol_table;
35099  symbol_table.add_constants();
35100  symbol_table.add_constant(x_var,x);
35101  symbol_table.add_constant(y_var,y);
35102 
35104  expression.register_symbol_table(symbol_table);
35105 
35106  parser<T> parser;
35107 
35108  if (parser.compile(expression_string,expression))
35109  {
35110  result = expression.value();
35111 
35112  return true;
35113  }
35114  else
35115  return false;
35116  }
35117 
35118  template <typename T>
35119  inline bool compute(const std::string& expression_string,
35120  const T& x, const T& y, const T& z,
35121  T& result)
35122  {
35123  // Only 'x', 'y' or 'z'
35124  static const std::string x_var("x");
35125  static const std::string y_var("y");
35126  static const std::string z_var("z");
35127 
35128  symbol_table<T> symbol_table;
35129  symbol_table.add_constants();
35130  symbol_table.add_constant(x_var,x);
35131  symbol_table.add_constant(y_var,y);
35132  symbol_table.add_constant(z_var,z);
35133 
35135  expression.register_symbol_table(symbol_table);
35136 
35137  parser<T> parser;
35138 
35139  if (parser.compile(expression_string,expression))
35140  {
35141  result = expression.value();
35142 
35143  return true;
35144  }
35145  else
35146  return false;
35147  }
35148 
35149  template <typename T, std::size_t N>
35150  class polynomial : public ifunction<T>
35151  {
35152  private:
35153 
35154  template <typename Type, std::size_t NumberOfCoefficients>
35155  struct poly_impl { };
35156 
35157  template <typename Type>
35158  struct poly_impl <Type,12>
35159  {
35160  static inline T evaluate(const Type x,
35161  const Type c12, const Type c11, const Type c10, const Type c9, const Type c8,
35162  const Type c7, const Type c6, const Type c5, const Type c4, const Type c3,
35163  const Type c2, const Type c1, const Type c0)
35164  {
35165  // p(x) = c_12x^12 + c_11x^11 + c_10x^10 + c_9x^9 + c_8x^8 + c_7x^7 + c_6x^6 + c_5x^5 + c_4x^4 + c_3x^3 + c_2x^2 + c_1x^1 + c_0x^0
35166  return ((((((((((((c12 * x + c11) * x + c10) * x + c9) * x + c8) * x + c7) * x + c6) * x + c5) * x + c4) * x + c3) * x + c2) * x + c1) * x + c0);
35167  }
35168  };
35169 
35170  template <typename Type>
35171  struct poly_impl <Type,11>
35172  {
35173  static inline T evaluate(const Type x,
35174  const Type c11, const Type c10, const Type c9, const Type c8, const Type c7,
35175  const Type c6, const Type c5, const Type c4, const Type c3, const Type c2,
35176  const Type c1, const Type c0)
35177  {
35178  // p(x) = c_11x^11 + c_10x^10 + c_9x^9 + c_8x^8 + c_7x^7 + c_6x^6 + c_5x^5 + c_4x^4 + c_3x^3 + c_2x^2 + c_1x^1 + c_0x^0
35179  return (((((((((((c11 * x + c10) * x + c9) * x + c8) * x + c7) * x + c6) * x + c5) * x + c4) * x + c3) * x + c2) * x + c1) * x + c0);
35180  }
35181  };
35182 
35183  template <typename Type>
35184  struct poly_impl <Type,10>
35185  {
35186  static inline T evaluate(const Type x,
35187  const Type c10, const Type c9, const Type c8, const Type c7, const Type c6,
35188  const Type c5, const Type c4, const Type c3, const Type c2, const Type c1,
35189  const Type c0)
35190  {
35191  // p(x) = c_10x^10 + c_9x^9 + c_8x^8 + c_7x^7 + c_6x^6 + c_5x^5 + c_4x^4 + c_3x^3 + c_2x^2 + c_1x^1 + c_0x^0
35192  return ((((((((((c10 * x + c9) * x + c8) * x + c7) * x + c6) * x + c5) * x + c4) * x + c3) * x + c2) * x + c1) * x + c0);
35193  }
35194  };
35195 
35196  template <typename Type>
35197  struct poly_impl <Type,9>
35198  {
35199  static inline T evaluate(const Type x,
35200  const Type c9, const Type c8, const Type c7, const Type c6, const Type c5,
35201  const Type c4, const Type c3, const Type c2, const Type c1, const Type c0)
35202  {
35203  // p(x) = c_9x^9 + c_8x^8 + c_7x^7 + c_6x^6 + c_5x^5 + c_4x^4 + c_3x^3 + c_2x^2 + c_1x^1 + c_0x^0
35204  return (((((((((c9 * x + c8) * x + c7) * x + c6) * x + c5) * x + c4) * x + c3) * x + c2) * x + c1) * x + c0);
35205  }
35206  };
35207 
35208  template <typename Type>
35209  struct poly_impl <Type,8>
35210  {
35211  static inline T evaluate(const Type x,
35212  const Type c8, const Type c7, const Type c6, const Type c5, const Type c4,
35213  const Type c3, const Type c2, const Type c1, const Type c0)
35214  {
35215  // p(x) = c_8x^8 + c_7x^7 + c_6x^6 + c_5x^5 + c_4x^4 + c_3x^3 + c_2x^2 + c_1x^1 + c_0x^0
35216  return ((((((((c8 * x + c7) * x + c6) * x + c5) * x + c4) * x + c3) * x + c2) * x + c1) * x + c0);
35217  }
35218  };
35219 
35220  template <typename Type>
35221  struct poly_impl <Type,7>
35222  {
35223  static inline T evaluate(const Type x,
35224  const Type c7, const Type c6, const Type c5, const Type c4, const Type c3,
35225  const Type c2, const Type c1, const Type c0)
35226  {
35227  // p(x) = c_7x^7 + c_6x^6 + c_5x^5 + c_4x^4 + c_3x^3 + c_2x^2 + c_1x^1 + c_0x^0
35228  return (((((((c7 * x + c6) * x + c5) * x + c4) * x + c3) * x + c2) * x + c1) * x + c0);
35229  }
35230  };
35231 
35232  template <typename Type>
35233  struct poly_impl <Type,6>
35234  {
35235  static inline T evaluate(const Type x,
35236  const Type c6, const Type c5, const Type c4, const Type c3, const Type c2,
35237  const Type c1, const Type c0)
35238  {
35239  // p(x) = c_6x^6 + c_5x^5 + c_4x^4 + c_3x^3 + c_2x^2 + c_1x^1 + c_0x^0
35240  return ((((((c6 * x + c5) * x + c4) * x + c3) * x + c2) * x + c1) * x + c0);
35241  }
35242  };
35243 
35244  template <typename Type>
35245  struct poly_impl <Type,5>
35246  {
35247  static inline T evaluate(const Type x,
35248  const Type c5, const Type c4, const Type c3, const Type c2,
35249  const Type c1, const Type c0)
35250  {
35251  // p(x) = c_5x^5 + c_4x^4 + c_3x^3 + c_2x^2 + c_1x^1 + c_0x^0
35252  return (((((c5 * x + c4) * x + c3) * x + c2) * x + c1) * x + c0);
35253  }
35254  };
35255 
35256  template <typename Type>
35257  struct poly_impl <Type,4>
35258  {
35259  static inline T evaluate(const Type x, const Type c4, const Type c3, const Type c2, const Type c1, const Type c0)
35260  {
35261  // p(x) = c_4x^4 + c_3x^3 + c_2x^2 + c_1x^1 + c_0x^0
35262  return ((((c4 * x + c3) * x + c2) * x + c1) * x + c0);
35263  }
35264  };
35265 
35266  template <typename Type>
35267  struct poly_impl <Type,3>
35268  {
35269  static inline T evaluate(const Type x, const Type c3, const Type c2, const Type c1, const Type c0)
35270  {
35271  // p(x) = c_3x^3 + c_2x^2 + c_1x^1 + c_0x^0
35272  return (((c3 * x + c2) * x + c1) * x + c0);
35273  }
35274  };
35275 
35276  template <typename Type>
35277  struct poly_impl <Type,2>
35278  {
35279  static inline T evaluate(const Type x, const Type c2, const Type c1, const Type c0)
35280  {
35281  // p(x) = c_2x^2 + c_1x^1 + c_0x^0
35282  return ((c2 * x + c1) * x + c0);
35283  }
35284  };
35285 
35286  template <typename Type>
35287  struct poly_impl <Type,1>
35288  {
35289  static inline T evaluate(const Type x, const Type c1, const Type c0)
35290  {
35291  // p(x) = c_1x^1 + c_0x^0
35292  return (c1 * x + c0);
35293  }
35294  };
35295 
35296  public:
35297 
35298  using ifunction<T>::operator();
35299 
35301  : ifunction<T>((N+2 <= 20) ? (N + 2) : std::numeric_limits<std::size_t>::max())
35302  {
35303  disable_has_side_effects(*this);
35304  }
35305 
35306  virtual ~polynomial()
35307  {}
35308 
35309  #define poly_rtrn(NN) \
35310  return (NN != N) ? std::numeric_limits<T>::quiet_NaN() :
35311 
35312  inline virtual T operator() (const T& x, const T& c1, const T& c0)
35313  {
35314  poly_rtrn(1) poly_impl<T,1>::evaluate(x,c1,c0);
35315  }
35316 
35317  inline virtual T operator() (const T& x, const T& c2, const T& c1, const T& c0)
35318  {
35319  poly_rtrn(2) poly_impl<T,2>::evaluate(x,c2,c1,c0);
35320  }
35321 
35322  inline virtual T operator() (const T& x, const T& c3, const T& c2, const T& c1, const T& c0)
35323  {
35324  poly_rtrn(3) poly_impl<T,3>::evaluate(x,c3,c2,c1,c0);
35325  }
35326 
35327  inline virtual T operator() (const T& x, const T& c4, const T& c3, const T& c2, const T& c1, const T& c0)
35328  {
35329  poly_rtrn(4) poly_impl<T,4>::evaluate(x,c4,c3,c2,c1,c0);
35330  }
35331 
35332  inline virtual T operator() (const T& x, const T& c5, const T& c4, const T& c3, const T& c2, const T& c1, const T& c0)
35333  {
35334  poly_rtrn(5) poly_impl<T,5>::evaluate(x,c5,c4,c3,c2,c1,c0);
35335  }
35336 
35337  inline virtual T operator() (const T& x, const T& c6, const T& c5, const T& c4, const T& c3, const T& c2, const T& c1, const T& c0)
35338  {
35339  poly_rtrn(6) poly_impl<T,6>::evaluate(x,c6,c5,c4,c3,c2,c1,c0);
35340  }
35341 
35342  inline virtual T operator() (const T& x, const T& c7, const T& c6, const T& c5, const T& c4, const T& c3, const T& c2, const T& c1, const T& c0)
35343  {
35344  poly_rtrn(7) poly_impl<T,7>::evaluate(x,c7,c6,c5,c4,c3,c2,c1,c0);
35345  }
35346 
35347  inline virtual T operator() (const T& x, const T& c8, const T& c7, const T& c6, const T& c5, const T& c4, const T& c3, const T& c2, const T& c1, const T& c0)
35348  {
35349  poly_rtrn(8) poly_impl<T,8>::evaluate(x,c8,c7,c6,c5,c4,c3,c2,c1,c0);
35350  }
35351 
35352  inline virtual T operator() (const T& x, const T& c9, const T& c8, const T& c7, const T& c6, const T& c5, const T& c4, const T& c3, const T& c2, const T& c1, const T& c0)
35353  {
35354  poly_rtrn(9) poly_impl<T,9>::evaluate(x,c9,c8,c7,c6,c5,c4,c3,c2,c1,c0);
35355  }
35356 
35357  inline virtual T operator() (const T& x, const T& c10, const T& c9, const T& c8, const T& c7, const T& c6, const T& c5, const T& c4, const T& c3, const T& c2, const T& c1, const T& c0)
35358  {
35359  poly_rtrn(10) poly_impl<T,10>::evaluate(x,c10,c9,c8,c7,c6,c5,c4,c3,c2,c1,c0);
35360  }
35361 
35362  inline virtual T operator() (const T& x, const T& c11, const T& c10, const T& c9, const T& c8, const T& c7, const T& c6, const T& c5, const T& c4, const T& c3, const T& c2, const T& c1, const T& c0)
35363  {
35364  poly_rtrn(11) poly_impl<T,11>::evaluate(x,c11,c10,c9,c8,c7,c6,c5,c4,c3,c2,c1,c0);
35365  }
35366 
35367  inline virtual T operator() (const T& x, const T& c12, const T& c11, const T& c10, const T& c9, const T& c8, const T& c7, const T& c6, const T& c5, const T& c4, const T& c3, const T& c2, const T& c1, const T& c0)
35368  {
35369  poly_rtrn(12) poly_impl<T,12>::evaluate(x,c12,c11,c10,c9,c8,c7,c6,c5,c4,c3,c2,c1,c0);
35370  }
35371 
35372  #undef poly_rtrn
35373 
35374  inline virtual T operator() ()
35375  {
35376  return std::numeric_limits<T>::quiet_NaN();
35377  }
35378 
35379  inline virtual T operator() (const T&)
35380  {
35381  return std::numeric_limits<T>::quiet_NaN();
35382  }
35383 
35384  inline virtual T operator() (const T&, const T&)
35385  {
35386  return std::numeric_limits<T>::quiet_NaN();
35387  }
35388  };
35389 
35390  template <typename T>
35391  class function_compositor
35392  {
35393  public:
35394 
35399 
35400  struct function
35401  {
35402  function()
35403  {}
35404 
35405  function(const std::string& n)
35406  : name_(n)
35407  {}
35408 
35409  function(const std::string& name,
35410  const std::string& expression)
35411  : name_(name),
35412  expression_(expression)
35413  {}
35414 
35415  function(const std::string& name,
35416  const std::string& expression,
35417  const std::string& v0)
35418  : name_(name),
35419  expression_(expression)
35420  {
35421  v_.push_back(v0);
35422  }
35423 
35424  function(const std::string& name,
35425  const std::string& expression,
35426  const std::string& v0, const std::string& v1)
35427  : name_(name),
35428  expression_(expression)
35429  {
35430  v_.push_back(v0); v_.push_back(v1);
35431  }
35432 
35433  function(const std::string& name,
35434  const std::string& expression,
35435  const std::string& v0, const std::string& v1,
35436  const std::string& v2)
35437  : name_(name),
35438  expression_(expression)
35439  {
35440  v_.push_back(v0); v_.push_back(v1);
35441  v_.push_back(v2);
35442  }
35443 
35444  function(const std::string& name,
35445  const std::string& expression,
35446  const std::string& v0, const std::string& v1,
35447  const std::string& v2, const std::string& v3)
35448  : name_(name),
35449  expression_(expression)
35450  {
35451  v_.push_back(v0); v_.push_back(v1);
35452  v_.push_back(v2); v_.push_back(v3);
35453  }
35454 
35455  function(const std::string& name,
35456  const std::string& expression,
35457  const std::string& v0, const std::string& v1,
35458  const std::string& v2, const std::string& v3,
35459  const std::string& v4)
35460  : name_(name),
35461  expression_(expression)
35462  {
35463  v_.push_back(v0); v_.push_back(v1);
35464  v_.push_back(v2); v_.push_back(v3);
35465  v_.push_back(v4);
35466  }
35467 
35468  inline function& name(const std::string& n)
35469  {
35470  name_ = n;
35471  return (*this);
35472  }
35473 
35474  inline function& expression(const std::string& e)
35475  {
35476  expression_ = e;
35477  return (*this);
35478  }
35479 
35480  inline function& var(const std::string& v)
35481  {
35482  v_.push_back(v);
35483  return (*this);
35484  }
35485 
35486  std::string name_;
35487  std::string expression_;
35488  std::deque<std::string> v_;
35489  };
35490 
35491  private:
35492 
35493  struct base_func : public exprtk::ifunction<T>
35494  {
35495  typedef const T& type;
35497  typedef std::vector<T*> varref_t;
35498  typedef std::vector<T> var_t;
35499  typedef std::pair<T*,std::size_t> lvarref_t;
35500  typedef std::vector<lvarref_t> lvr_vec_t;
35501 
35503 
35504  base_func(const std::size_t& pc = 0)
35505  : exprtk::ifunction<T>(pc),
35506  local_var_stack_size(0),
35507  stack_depth(0)
35508  {
35509  v.resize(pc);
35510  }
35511 
35512  virtual ~base_func()
35513  {}
35514 
35515  inline void update(const T& v0)
35516  {
35517  (*v[0]) = v0;
35518  }
35519 
35520  inline void update(const T& v0, const T& v1)
35521  {
35522  (*v[0]) = v0; (*v[1]) = v1;
35523  }
35524 
35525  inline void update(const T& v0, const T& v1, const T& v2)
35526  {
35527  (*v[0]) = v0; (*v[1]) = v1;
35528  (*v[2]) = v2;
35529  }
35530 
35531  inline void update(const T& v0, const T& v1, const T& v2, const T& v3)
35532  {
35533  (*v[0]) = v0; (*v[1]) = v1;
35534  (*v[2]) = v2; (*v[3]) = v3;
35535  }
35536 
35537  inline void update(const T& v0, const T& v1, const T& v2, const T& v3, const T& v4)
35538  {
35539  (*v[0]) = v0; (*v[1]) = v1;
35540  (*v[2]) = v2; (*v[3]) = v3;
35541  (*v[4]) = v4;
35542  }
35543 
35544  inline void update(const T& v0, const T& v1, const T& v2, const T& v3, const T& v4, const T& v5)
35545  {
35546  (*v[0]) = v0; (*v[1]) = v1;
35547  (*v[2]) = v2; (*v[3]) = v3;
35548  (*v[4]) = v4; (*v[5]) = v5;
35549  }
35550 
35551  inline function_t& setup(expression_t& expr)
35552  {
35553  expression = expr;
35554 
35555  typedef typename expression_t::control_block::local_data_list_t ldl_t;
35556 
35557  ldl_t ldl = expr.local_data_list();
35558 
35559  std::vector<std::size_t> index_list;
35560 
35561  for (std::size_t i = 0; i < ldl.size(); ++i)
35562  {
35563  if (ldl[i].size)
35564  {
35565  index_list.push_back(i);
35566  }
35567  }
35568 
35569  std::size_t input_param_count = 0;
35570 
35571  for (std::size_t i = 0; i < index_list.size(); ++i)
35572  {
35573  const std::size_t index = index_list[i];
35574 
35575  if (i < (index_list.size() - v.size()))
35576  {
35577  lv.push_back(
35578  std::make_pair(
35579  reinterpret_cast<T*>(ldl[index].pointer),
35580  ldl[index].size));
35581 
35582  local_var_stack_size += ldl[index].size;
35583  }
35584  else
35585  v[input_param_count++] = reinterpret_cast<T*>(ldl[index].pointer);
35586  }
35587 
35588  clear_stack();
35589 
35590  return (*this);
35591  }
35592 
35593  inline void pre()
35594  {
35595  if (stack_depth++)
35596  {
35597  if (!v.empty())
35598  {
35599  var_t var_stack(v.size(),T(0));
35600  copy(v,var_stack);
35601  param_stack.push_back(var_stack);
35602  }
35603 
35604  if (!lv.empty())
35605  {
35606  var_t local_var_stack(local_var_stack_size,T(0));
35607  copy(lv,local_var_stack);
35608  local_stack.push_back(local_var_stack);
35609  }
35610  }
35611  }
35612 
35613  inline void post()
35614  {
35615  if (--stack_depth)
35616  {
35617  if (!v.empty())
35618  {
35619  copy(param_stack.back(),v);
35620  param_stack.pop_back();
35621  }
35622 
35623  if (!lv.empty())
35624  {
35625  copy(local_stack.back(),lv);
35626  local_stack.pop_back();
35627  }
35628  }
35629  }
35630 
35631  void copy(const varref_t& src_v, var_t& dest_v)
35632  {
35633  for (std::size_t i = 0; i < src_v.size(); ++i)
35634  {
35635  dest_v[i] = (*src_v[i]);
35636  }
35637  }
35638 
35639  void copy(const var_t& src_v, varref_t& dest_v)
35640  {
35641  for (std::size_t i = 0; i < src_v.size(); ++i)
35642  {
35643  (*dest_v[i]) = src_v[i];
35644  }
35645  }
35646 
35647  void copy(const lvr_vec_t& src_v, var_t& dest_v)
35648  {
35649  typename var_t::iterator itr = dest_v.begin();
35650  typedef typename std::iterator_traits<typename var_t::iterator>::difference_type diff_t;
35651 
35652  for (std::size_t i = 0; i < src_v.size(); ++i)
35653  {
35654  lvarref_t vr = src_v[i];
35655 
35656  if (1 == vr.second)
35657  *itr++ = (*vr.first);
35658  else
35659  {
35660  std::copy(vr.first, vr.first + vr.second, itr);
35661  itr += static_cast<diff_t>(vr.second);
35662  }
35663  }
35664  }
35665 
35666  void copy(const var_t& src_v, lvr_vec_t& dest_v)
35667  {
35668  typename var_t::const_iterator itr = src_v.begin();
35669  typedef typename std::iterator_traits<typename var_t::iterator>::difference_type diff_t;
35670 
35671  for (std::size_t i = 0; i < src_v.size(); ++i)
35672  {
35673  lvarref_t vr = dest_v[i];
35674 
35675  if (1 == vr.second)
35676  (*vr.first) = *itr++;
35677  else
35678  {
35679  std::copy(itr, itr + static_cast<diff_t>(vr.second), vr.first);
35680  itr += static_cast<diff_t>(vr.second);
35681  }
35682  }
35683  }
35684 
35685  inline void clear_stack()
35686  {
35687  for (std::size_t i = 0; i < v.size(); ++i)
35688  {
35689  (*v[i]) = 0;
35690  }
35691  }
35692 
35693  inline virtual T value(expression_t& e)
35694  {
35695  return e.value();
35696  }
35697 
35702  std::size_t stack_depth;
35703  std::deque<var_t> param_stack;
35704  std::deque<var_t> local_stack;
35705  };
35706 
35707  typedef std::map<std::string,base_func*> funcparam_t;
35708 
35709  struct func_0param : public base_func
35710  {
35712 
35714 
35715  inline T operator() ()
35716  {
35717  return this->value(base_func::expression);
35718  }
35719  };
35720 
35721  typedef const T& type;
35722 
35723  template <typename BaseFuncType>
35724  struct scoped_bft
35725  {
35726  scoped_bft(BaseFuncType& bft) : bft_(bft) { bft_.pre (); }
35727  ~scoped_bft() { bft_.post(); }
35728 
35729  BaseFuncType& bft_;
35730 
35731  private:
35732 
35734  scoped_bft& operator=(scoped_bft&);
35735  };
35736 
35737  struct func_1param : public base_func
35738  {
35740 
35742 
35743  inline T operator() (type v0)
35744  {
35745  scoped_bft<func_1param> sb(*this);
35746  base_func::update(v0);
35747  return this->value(base_func::expression);
35748  }
35749  };
35750 
35751  struct func_2param : public base_func
35752  {
35754 
35756 
35757  inline T operator() (type v0, type v1)
35758  {
35759  scoped_bft<func_2param> sb(*this);
35760  base_func::update(v0, v1);
35761  return this->value(base_func::expression);
35762  }
35763  };
35764 
35765  struct func_3param : public base_func
35766  {
35768 
35770 
35771  inline T operator() (type v0, type v1, type v2)
35772  {
35773  scoped_bft<func_3param> sb(*this);
35774  base_func::update(v0, v1, v2);
35775  return this->value(base_func::expression);
35776  }
35777  };
35778 
35779  struct func_4param : public base_func
35780  {
35782 
35784 
35785  inline T operator() (type v0, type v1, type v2, type v3)
35786  {
35787  scoped_bft<func_4param> sb(*this);
35788  base_func::update(v0, v1, v2, v3);
35789  return this->value(base_func::expression);
35790  }
35791  };
35792 
35793  struct func_5param : public base_func
35794  {
35796 
35798 
35799  inline T operator() (type v0, type v1, type v2, type v3, type v4)
35800  {
35801  scoped_bft<func_5param> sb(*this);
35802  base_func::update(v0, v1, v2, v3, v4);
35803  return this->value(base_func::expression);
35804  }
35805  };
35806 
35807  struct func_6param : public base_func
35808  {
35810 
35812 
35813  inline T operator() (type v0, type v1, type v2, type v3, type v4, type v5)
35814  {
35815  scoped_bft<func_6param> sb(*this);
35816  base_func::update(v0, v1, v2, v3, v4, v5);
35817  return this->value(base_func::expression);
35818  }
35819  };
35820 
35822  {
35823  typedef exprtk::results_context<T> results_context_t;
35824  typedef typename results_context_t::type_store_t type_t;
35825  typedef typename type_t::scalar_view scalar_t;
35826 
35827  T result = e.value();
35828 
35829  if (e.return_invoked())
35830  {
35831  // Due to the post compilation checks, it can be safely
35832  // assumed that there will be at least one parameter
35833  // and that the first parameter will always be scalar.
35834  return scalar_t(e.results()[0])();
35835  }
35836 
35837  return result;
35838  }
35839 
35840  #define def_fp_retval(N) \
35841  struct func_##N##param_retval : public func_##N##param \
35842  { \
35843  inline T value(expression_t& e) \
35844  { \
35845  return return_value(e); \
35846  } \
35847  }; \
35848 
35849  def_fp_retval(0)
35850  def_fp_retval(1)
35851  def_fp_retval(2)
35852  def_fp_retval(3)
35853  def_fp_retval(4)
35854  def_fp_retval(5)
35855  def_fp_retval(6)
35856 
35857  template <typename Allocator,
35858  template <typename,typename> class Sequence>
35859  inline bool add(const std::string& name,
35860  const std::string& expression,
35861  const Sequence<std::string,Allocator>& var_list,
35862  const bool override = false)
35863  {
35864  const typename std::map<std::string,expression_t>::iterator itr = expr_map_.find(name);
35865 
35866  if (expr_map_.end() != itr)
35867  {
35868  if (!override)
35869  {
35870  exprtk_debug(("Compositor error(add): function '%s' already defined\n",
35871  name.c_str()));
35872 
35873  return false;
35874  }
35875 
35876  remove(name, var_list.size());
35877  }
35878 
35879  if (compile_expression(name,expression,var_list))
35880  {
35881  const std::size_t n = var_list.size();
35882 
35883  fp_map_[n][name]->setup(expr_map_[name]);
35884 
35885  return true;
35886  }
35887  else
35888  {
35889  exprtk_debug(("Compositor error(add): Failed to compile function '%s'\n",
35890  name.c_str()));
35891 
35892  return false;
35893  }
35894  }
35895 
35896  public:
35897 
35899  : parser_(settings_t::compile_all_opts +
35900  settings_t::e_disable_zero_return),
35901  fp_map_(7)
35902  {}
35903 
35905  : symbol_table_(st),
35906  parser_(settings_t::compile_all_opts +
35907  settings_t::e_disable_zero_return),
35908  fp_map_(7)
35909  {}
35910 
35912  {
35913  clear();
35914  }
35915 
35917  {
35918  return symbol_table_;
35919  }
35920 
35922  {
35923  auxiliary_symtab_list_.push_back(&symtab);
35924  }
35925 
35926  void clear()
35927  {
35928  symbol_table_.clear();
35929  expr_map_ .clear();
35930 
35931  for (std::size_t i = 0; i < fp_map_.size(); ++i)
35932  {
35933  typename funcparam_t::iterator itr = fp_map_[i].begin();
35934  typename funcparam_t::iterator end = fp_map_[i].end ();
35935 
35936  while (itr != end)
35937  {
35938  delete itr->second;
35939  ++itr;
35940  }
35941 
35942  fp_map_[i].clear();
35943  }
35944  }
35945 
35946  inline bool add(const function& f, const bool override = false)
35947  {
35948  return add(f.name_, f.expression_, f.v_,override);
35949  }
35950 
35951  private:
35952 
35953  template <typename Allocator,
35954  template <typename,typename> class Sequence>
35955  bool compile_expression(const std::string& name,
35956  const std::string& expression,
35957  const Sequence<std::string,Allocator>& input_var_list,
35958  bool return_present = false)
35959  {
35960  expression_t compiled_expression;
35961  symbol_table_t local_symbol_table;
35962 
35963  local_symbol_table.load_from(symbol_table_);
35964  local_symbol_table.add_constants();
35965 
35966  if (!valid(name,input_var_list.size()))
35967  return false;
35968 
35969  if (!forward(name,
35970  input_var_list.size(),
35971  local_symbol_table,
35972  return_present))
35973  return false;
35974 
35975  compiled_expression.register_symbol_table(local_symbol_table);
35976 
35977  for (std::size_t i = 0; i < auxiliary_symtab_list_.size(); ++i)
35978  {
35979  compiled_expression.register_symbol_table((*auxiliary_symtab_list_[i]));
35980  }
35981 
35982  std::string mod_expression;
35983 
35984  for (std::size_t i = 0; i < input_var_list.size(); ++i)
35985  {
35986  mod_expression += " var " + input_var_list[i] + "{};\n";
35987  }
35988 
35989  if (
35990  ('{' == details::front(expression)) &&
35991  ('}' == details::back (expression))
35992  )
35993  mod_expression += "~" + expression + ";";
35994  else
35995  mod_expression += "~{" + expression + "};";
35996 
35997  if (!parser_.compile(mod_expression,compiled_expression))
35998  {
35999  exprtk_debug(("Compositor Error: %s\n",parser_.error().c_str()));
36000  exprtk_debug(("Compositor modified expression: \n%s\n",mod_expression.c_str()));
36001 
36002  remove(name,input_var_list.size());
36003 
36004  return false;
36005  }
36006 
36007  if (!return_present && parser_.dec().return_present())
36008  {
36009  remove(name,input_var_list.size());
36010 
36011  return compile_expression(name, expression, input_var_list, true);
36012  }
36013 
36014  // Make sure every return point has a scalar as its first parameter
36015  if (parser_.dec().return_present())
36016  {
36017  typedef std::vector<std::string> str_list_t;
36018 
36019  str_list_t ret_param_list = parser_.dec().return_param_type_list();
36020 
36021  for (std::size_t i = 0; i < ret_param_list.size(); ++i)
36022  {
36023  const std::string& params = ret_param_list[i];
36024 
36025  if (params.empty() || ('T' != params[0]))
36026  {
36027  exprtk_debug(("Compositor Error: Return statement in function '%s' is invalid\n",
36028  name.c_str()));
36029 
36030  remove(name,input_var_list.size());
36031 
36032  return false;
36033  }
36034  }
36035  }
36036 
36037  expr_map_[name] = compiled_expression;
36038 
36039  exprtk::ifunction<T>& ifunc = (*(fp_map_[input_var_list.size()])[name]);
36040 
36041  if (symbol_table_.add_function(name,ifunc))
36042  return true;
36043  else
36044  {
36045  exprtk_debug(("Compositor Error: Failed to add function '%s' to symbol table\n",
36046  name.c_str()));
36047  return false;
36048  }
36049  }
36050 
36051  inline bool symbol_used(const std::string& symbol) const
36052  {
36053  return (
36054  symbol_table_.is_variable (symbol) ||
36055  symbol_table_.is_stringvar (symbol) ||
36056  symbol_table_.is_function (symbol) ||
36057  symbol_table_.is_vector (symbol) ||
36058  symbol_table_.is_vararg_function(symbol)
36059  );
36060  }
36061 
36062  inline bool valid(const std::string& name,
36063  const std::size_t& arg_count) const
36064  {
36065  if (arg_count > 6)
36066  return false;
36067  else if (symbol_used(name))
36068  return false;
36069  else if (fp_map_[arg_count].end() != fp_map_[arg_count].find(name))
36070  return false;
36071  else
36072  return true;
36073  }
36074 
36075  inline bool forward(const std::string& name,
36076  const std::size_t& arg_count,
36077  symbol_table_t& sym_table,
36078  const bool ret_present = false)
36079  {
36080  switch (arg_count)
36081  {
36082  #define case_stmt(N) \
36083  case N : (fp_map_[arg_count])[name] = \
36084  (!ret_present) ? static_cast<base_func*> \
36085  (new func_##N##param) : \
36086  static_cast<base_func*> \
36087  (new func_##N##param_retval) ; \
36088  break; \
36089 
36090  case_stmt(0) case_stmt(1) case_stmt(2)
36091  case_stmt(3) case_stmt(4) case_stmt(5)
36092  case_stmt(6)
36093  #undef case_stmt
36094  }
36095 
36096  exprtk::ifunction<T>& ifunc = (*(fp_map_[arg_count])[name]);
36097 
36098  return sym_table.add_function(name,ifunc);
36099  }
36100 
36101  inline void remove(const std::string& name, const std::size_t& arg_count)
36102  {
36103  if (arg_count > 6)
36104  return;
36105 
36106  const typename std::map<std::string,expression_t>::iterator em_itr = expr_map_.find(name);
36107 
36108  if (expr_map_.end() != em_itr)
36109  {
36110  expr_map_.erase(em_itr);
36111  }
36112 
36113  const typename funcparam_t::iterator fp_itr = fp_map_[arg_count].find(name);
36114 
36115  if (fp_map_[arg_count].end() != fp_itr)
36116  {
36117  delete fp_itr->second;
36118  fp_map_[arg_count].erase(fp_itr);
36119  }
36120 
36121  symbol_table_.remove_function(name);
36122  }
36123 
36124  private:
36125 
36128  std::map<std::string,expression_t> expr_map_;
36129  std::vector<funcparam_t> fp_map_;
36130  std::vector<symbol_table_t*> auxiliary_symtab_list_;
36131  };
36132 
36133  template <typename T>
36134  inline bool pgo_primer()
36135  {
36136  static const std::string expression_list[]
36137  = {
36138  "(y + x)",
36139  "2 * (y + x)",
36140  "(2 * y + 2 * x)",
36141  "(y + x / y) * (x - y / x)",
36142  "x / ((x + y) * (x - y)) / y",
36143  "1 - ((x * y) + (y / x)) - 3",
36144  "sin(2 * x) + cos(pi / y)",
36145  "1 - sin(2 * x) + cos(pi / y)",
36146  "sqrt(1 - sin(2 * x) + cos(pi / y) / 3)",
36147  "(x^2 / sin(2 * pi / y)) -x / 2",
36148  "x + (cos(y - sin(2 / x * pi)) - sin(x - cos(2 * y / pi))) - y",
36149  "clamp(-1.0, sin(2 * pi * x) + cos(y / 2 * pi), +1.0)",
36150  "iclamp(-1.0, sin(2 * pi * x) + cos(y / 2 * pi), +1.0)",
36151  "max(3.33, min(sqrt(1 - sin(2 * x) + cos(pi / y) / 3), 1.11))",
36152  "if(avg(x,y) <= x + y, x - y, x * y) + 2 * pi / x",
36153  "1.1x^1 + 2.2y^2 - 3.3x^3 + 4.4y^4 - 5.5x^5 + 6.6y^6 - 7.7x^27 + 8.8y^55",
36154  "(yy + xx)",
36155  "2 * (yy + xx)",
36156  "(2 * yy + 2 * xx)",
36157  "(yy + xx / yy) * (xx - yy / xx)",
36158  "xx / ((xx + yy) * (xx - yy)) / yy",
36159  "1 - ((xx * yy) + (yy / xx)) - 3",
36160  "sin(2 * xx) + cos(pi / yy)",
36161  "1 - sin(2 * xx) + cos(pi / yy)",
36162  "sqrt(1 - sin(2 * xx) + cos(pi / yy) / 3)",
36163  "(xx^2 / sin(2 * pi / yy)) -xx / 2",
36164  "xx + (cos(yy - sin(2 / xx * pi)) - sin(xx - cos(2 * yy / pi))) - yy",
36165  "clamp(-1.0, sin(2 * pi * xx) + cos(yy / 2 * pi), +1.0)",
36166  "max(3.33, min(sqrt(1 - sin(2 * xx) + cos(pi / yy) / 3), 1.11))",
36167  "if(avg(xx,yy) <= xx + yy, xx - yy, xx * yy) + 2 * pi / xx",
36168  "1.1xx^1 + 2.2yy^2 - 3.3xx^3 + 4.4yy^4 - 5.5xx^5 + 6.6yy^6 - 7.7xx^27 + 8.8yy^55",
36169  "(1.1*(2.2*(3.3*(4.4*(5.5*(6.6*(7.7*(8.8*(9.9+x)))))))))",
36170  "(((((((((x+9.9)*8.8)*7.7)*6.6)*5.5)*4.4)*3.3)*2.2)*1.1)",
36171  "(x + y) * z", "x + (y * z)", "(x + y) * 7", "x + (y * 7)",
36172  "(x + 7) * y", "x + (7 * y)", "(7 + x) * y", "7 + (x * y)",
36173  "(2 + x) * 3", "2 + (x * 3)", "(2 + 3) * x", "2 + (3 * x)",
36174  "(x + 2) * 3", "x + (2 * 3)",
36175  "(x + y) * (z / w)", "(x + y) * (z / 7)", "(x + y) * (7 / z)", "(x + 7) * (y / z)",
36176  "(7 + x) * (y / z)", "(2 + x) * (y / z)", "(x + 2) * (y / 3)", "(2 + x) * (y / 3)",
36177  "(x + 2) * (3 / y)", "x + (y * (z / w))", "x + (y * (z / 7))", "x + (y * (7 / z))",
36178  "x + (7 * (y / z))", "7 + (x * (y / z))", "2 + (x * (3 / y))", "x + (2 * (y / 4))",
36179  "2 + (x * (y / 3))", "x + (2 * (3 / y))",
36180  "x + ((y * z) / w)", "x + ((y * z) / 7)", "x + ((y * 7) / z)", "x + ((7 * y) / z)",
36181  "7 + ((y * z) / w)", "2 + ((x * 3) / y)", "x + ((2 * y) / 3)", "2 + ((x * y) / 3)",
36182  "x + ((2 * 3) / y)", "(((x + y) * z) / w)",
36183  "(((x + y) * z) / 7)", "(((x + y) * 7) / z)", "(((x + 7) * y) / z)", "(((7 + x) * y) / z)",
36184  "(((2 + x) * 3) / y)", "(((x + 2) * y) / 3)", "(((2 + x) * y) / 3)", "(((x + 2) * 3) / y)",
36185  "((x + (y * z)) / w)", "((x + (y * z)) / 7)", "((x + (y * 7)) / y)", "((x + (7 * y)) / z)",
36186  "((7 + (x * y)) / z)", "((2 + (x * 3)) / y)", "((x + (2 * y)) / 3)", "((2 + (x * y)) / 3)",
36187  "((x + (2 * 3)) / y)",
36188  "(xx + yy) * zz", "xx + (yy * zz)",
36189  "(xx + yy) * 7", "xx + (yy * 7)",
36190  "(xx + 7) * yy", "xx + (7 * yy)",
36191  "(7 + xx) * yy", "7 + (xx * yy)",
36192  "(2 + x) * 3", "2 + (x * 3)",
36193  "(2 + 3) * x", "2 + (3 * x)",
36194  "(x + 2) * 3", "x + (2 * 3)",
36195  "(xx + yy) * (zz / ww)", "(xx + yy) * (zz / 7)",
36196  "(xx + yy) * (7 / zz)", "(xx + 7) * (yy / zz)",
36197  "(7 + xx) * (yy / zz)", "(2 + xx) * (yy / zz)",
36198  "(xx + 2) * (yy / 3)", "(2 + xx) * (yy / 3)",
36199  "(xx + 2) * (3 / yy)", "xx + (yy * (zz / ww))",
36200  "xx + (yy * (zz / 7))", "xx + (yy * (7 / zz))",
36201  "xx + (7 * (yy / zz))", "7 + (xx * (yy / zz))",
36202  "2 + (xx * (3 / yy))", "xx + (2 * (yy / 4))",
36203  "2 + (xx * (yy / 3))", "xx + (2 * (3 / yy))",
36204  "xx + ((yy * zz) / ww)", "xx + ((yy * zz) / 7)",
36205  "xx + ((yy * 7) / zz)", "xx + ((7 * yy) / zz)",
36206  "7 + ((yy * zz) / ww)", "2 + ((xx * 3) / yy)",
36207  "xx + ((2 * yy) / 3)", "2 + ((xx * yy) / 3)",
36208  "xx + ((2 * 3) / yy)", "(((xx + yy) * zz) / ww)",
36209  "(((xx + yy) * zz) / 7)", "(((xx + yy) * 7) / zz)",
36210  "(((xx + 7) * yy) / zz)", "(((7 + xx) * yy) / zz)",
36211  "(((2 + xx) * 3) / yy)", "(((xx + 2) * yy) / 3)",
36212  "(((2 + xx) * yy) / 3)", "(((xx + 2) * 3) / yy)",
36213  "((xx + (yy * zz)) / ww)", "((xx + (yy * zz)) / 7)",
36214  "((xx + (yy * 7)) / yy)", "((xx + (7 * yy)) / zz)",
36215  "((7 + (xx * yy)) / zz)", "((2 + (xx * 3)) / yy)",
36216  "((xx + (2 * yy)) / 3)", "((2 + (xx * yy)) / 3)",
36217  "((xx + (2 * 3)) / yy)"
36218  };
36219  static const std::size_t expression_list_size = sizeof(expression_list) / sizeof(std::string);
36220 
36221  T x = T(0);
36222  T y = T(0);
36223  T z = T(0);
36224  T w = T(0);
36225  T xx = T(0);
36226  T yy = T(0);
36227  T zz = T(0);
36228  T ww = T(0);
36229 
36230  exprtk::symbol_table<T> symbol_table;
36231  symbol_table.add_constants();
36232  symbol_table.add_variable( "x", x);
36233  symbol_table.add_variable( "y", y);
36234  symbol_table.add_variable( "z", z);
36235  symbol_table.add_variable( "w", w);
36236  symbol_table.add_variable("xx",xx);
36237  symbol_table.add_variable("yy",yy);
36238  symbol_table.add_variable("zz",zz);
36239  symbol_table.add_variable("ww",ww);
36240 
36241  typedef typename std::deque<exprtk::expression<T> > expr_list_t;
36242  expr_list_t expr_list;
36243 
36244  const std::size_t rounds = 50;
36245 
36246  {
36247  for (std::size_t r = 0; r < rounds; ++r)
36248  {
36249  expr_list.clear();
36250  exprtk::parser<T> parser;
36251 
36252  for (std::size_t i = 0; i < expression_list_size; ++i)
36253  {
36255  expression.register_symbol_table(symbol_table);
36256 
36257  if (!parser.compile(expression_list[i],expression))
36258  {
36259  return false;
36260  }
36261 
36262  expr_list.push_back(expression);
36263  }
36264  }
36265  }
36266 
36267  struct execute
36268  {
36269  static inline T process(T& x, T& y, expression<T>& expression)
36270  {
36271  static const T lower_bound = T(-20);
36272  static const T upper_bound = T(+20);
36273  static const T delta = T(0.1);
36274 
36275  T total = T(0);
36276 
36277  for (x = lower_bound; x <= upper_bound; x += delta)
36278  {
36279  for (y = lower_bound; y <= upper_bound; y += delta)
36280  {
36281  total += expression.value();
36282  }
36283  }
36284 
36285  return total;
36286  }
36287  };
36288 
36289  for (std::size_t i = 0; i < expr_list.size(); ++i)
36290  {
36291  execute::process( x, y, expr_list[i]);
36292  execute::process(xx, yy, expr_list[i]);
36293  }
36294 
36295  {
36296  for (std::size_t i = 0; i < 10000; ++i)
36297  {
36298  const T v = T(123.456 + i);
36299 
36301  return false;
36302 
36303  #define else_stmt(N) \
36304  else if (details::is_true(details::numeric::nequal(details::numeric::fast_exp<T,N>::result(v),details::numeric::pow(v,T(N))))) \
36305  return false; \
36306 
36307  else_stmt( 2) else_stmt( 3) else_stmt( 4) else_stmt( 5)
36308  else_stmt( 6) else_stmt( 7) else_stmt( 8) else_stmt( 9)
36309  else_stmt(10) else_stmt(11) else_stmt(12) else_stmt(13)
36310  else_stmt(14) else_stmt(15) else_stmt(16) else_stmt(17)
36311  else_stmt(18) else_stmt(19) else_stmt(20) else_stmt(21)
36312  else_stmt(22) else_stmt(23) else_stmt(24) else_stmt(25)
36313  else_stmt(26) else_stmt(27) else_stmt(28) else_stmt(29)
36314  else_stmt(30) else_stmt(31) else_stmt(32) else_stmt(33)
36315  else_stmt(34) else_stmt(35) else_stmt(36) else_stmt(37)
36316  else_stmt(38) else_stmt(39) else_stmt(40) else_stmt(41)
36317  else_stmt(42) else_stmt(43) else_stmt(44) else_stmt(45)
36318  else_stmt(46) else_stmt(47) else_stmt(48) else_stmt(49)
36319  else_stmt(50) else_stmt(51) else_stmt(52) else_stmt(53)
36320  else_stmt(54) else_stmt(55) else_stmt(56) else_stmt(57)
36321  else_stmt(58) else_stmt(59) else_stmt(60) else_stmt(61)
36322  }
36323  }
36324 
36325  return true;
36326  }
36327 }
36328 
36329 #if defined(_WIN32) || defined(__WIN32__) || defined(WIN32)
36330 # ifndef NOMINMAX
36331 # define NOMINMAX
36332 # endif
36333 # ifndef WIN32_LEAN_AND_MEAN
36334 # define WIN32_LEAN_AND_MEAN
36335 # endif
36336 # include <windows.h>
36337 # include <ctime>
36338 #else
36339 # include <ctime>
36340 # include <sys/time.h>
36341 # include <sys/types.h>
36342 #endif
36343 
36344 namespace exprtk
36345 {
36346  class timer
36347  {
36348  public:
36349 
36350  #if defined(_WIN32) || defined(__WIN32__) || defined(WIN32)
36351  timer()
36352  : in_use_(false)
36353  {
36354  QueryPerformanceFrequency(&clock_frequency_);
36355  }
36356 
36357  inline void start()
36358  {
36359  in_use_ = true;
36360  QueryPerformanceCounter(&start_time_);
36361  }
36362 
36363  inline void stop()
36364  {
36365  QueryPerformanceCounter(&stop_time_);
36366  in_use_ = false;
36367  }
36368 
36369  inline double time() const
36370  {
36371  return (1.0 * (stop_time_.QuadPart - start_time_.QuadPart)) / (1.0 * clock_frequency_.QuadPart);
36372  }
36373 
36374  #else
36375 
36377  : in_use_(false)
36378  {
36379  start_time_.tv_sec = 0;
36380  start_time_.tv_usec = 0;
36381  stop_time_.tv_sec = 0;
36382  stop_time_.tv_usec = 0;
36383  }
36384 
36385  inline void start()
36386  {
36387  in_use_ = true;
36388  gettimeofday(&start_time_,0);
36389  }
36390 
36391  inline void stop()
36392  {
36393  gettimeofday(&stop_time_, 0);
36394  in_use_ = false;
36395  }
36396 
36397  inline unsigned long long int usec_time() const
36398  {
36399  if (!in_use_)
36400  {
36401  if (stop_time_.tv_sec >= start_time_.tv_sec)
36402  {
36403  return 1000000LLU * static_cast<unsigned long long int>(stop_time_.tv_sec - start_time_.tv_sec ) +
36404  static_cast<unsigned long long int>(stop_time_.tv_usec - start_time_.tv_usec) ;
36405  }
36406  else
36408  }
36409  else
36411  }
36412 
36413  inline double time() const
36414  {
36415  return usec_time() * 0.000001;
36416  }
36417 
36418  #endif
36419 
36420  inline bool in_use() const
36421  {
36422  return in_use_;
36423  }
36424 
36425  private:
36426 
36427  bool in_use_;
36428 
36429  #if defined(_WIN32) || defined(__WIN32__) || defined(WIN32)
36430  LARGE_INTEGER start_time_;
36431  LARGE_INTEGER stop_time_;
36432  LARGE_INTEGER clock_frequency_;
36433  #else
36434  struct timeval start_time_;
36435  struct timeval stop_time_;
36436  #endif
36437  };
36438 
36439 } // namespace exprtk
36440 
36441 #ifndef exprtk_disable_rtl_io
36442 namespace exprtk
36443 {
36444  namespace rtl { namespace io { namespace details
36445  {
36446  template <typename T>
36447  inline void print_type(const std::string& fmt,
36448  const T v,
36450  {
36451  printf(fmt.c_str(),v);
36452  }
36453 
36454  template <typename T>
36455  struct print_impl
36456  {
36463 
36464  static void process(const std::string& scalar_format, parameter_list_t parameters)
36465  {
36466  for (std::size_t i = 0; i < parameters.size(); ++i)
36467  {
36468  generic_type& gt = parameters[i];
36469 
36470  switch (gt.type)
36471  {
36472  case generic_type::e_scalar : print(scalar_format,scalar_t(gt));
36473  break;
36474 
36475  case generic_type::e_vector : print(scalar_format,vector_t(gt));
36476  break;
36477 
36479  break;
36480 
36481  default : continue;
36482  }
36483  }
36484  }
36485 
36486  static inline void print(const std::string& scalar_format, const scalar_t& s)
36487  {
36488  print_type(scalar_format,s(),num_type());
36489  }
36490 
36491  static inline void print(const std::string& scalar_format, const vector_t& v)
36492  {
36493  for (std::size_t i = 0; i < v.size(); ++i)
36494  {
36495  print_type(scalar_format,v[i],num_type());
36496 
36497  if ((i + 1) < v.size())
36498  printf(" ");
36499  }
36500  }
36501 
36502  static inline void print(const string_t& s)
36503  {
36504  printf("%s",to_str(s).c_str());
36505  }
36506  };
36507 
36508  } // namespace exprtk::rtl::io::details
36509 
36510  template <typename T>
36512  {
36514 
36516 
36517  print(const std::string& scalar_format = "%10.5f")
36518  : scalar_format_(scalar_format)
36519  {
36521  }
36522 
36523  inline T operator() (parameter_list_t parameters)
36524  {
36526  return T(0);
36527  }
36528 
36529  std::string scalar_format_;
36530  };
36531 
36532  template <typename T>
36534  {
36536 
36538 
36539  println(const std::string& scalar_format = "%10.5f")
36540  : scalar_format_(scalar_format)
36541  {
36543  }
36544 
36545  inline T operator() (parameter_list_t parameters)
36546  {
36548  printf("\n");
36549  return T(0);
36550  }
36551 
36552  std::string scalar_format_;
36553  };
36554 
36555  template <typename T>
36556  struct package
36557  {
36560 
36562  {
36563  #define exprtk_register_function(FunctionName,FunctionType) \
36564  if (!symtab.add_function(FunctionName,FunctionType)) \
36565  { \
36566  exprtk_debug(( \
36567  "exprtk::rtl::io::register_package - Failed to add function: %s\n", \
36568  FunctionName)); \
36569  return false; \
36570  } \
36571 
36572  exprtk_register_function("print" , p)
36573  exprtk_register_function("println", pl)
36574  #undef exprtk_register_function
36575 
36576  return true;
36577  }
36578  };
36579 
36580  } // namespace exprtk::rtl::io
36581  } // namespace exprtk::rtl
36582 } // namespace exprtk
36583 #endif
36584 
36585 #ifndef exprtk_disable_rtl_io_file
36586 #include <fstream>
36587 namespace exprtk
36588 {
36589  namespace rtl { namespace io { namespace file { namespace details
36590  {
36592  {
36593  e_error = 0,
36594  e_read = 1,
36595  e_write = 2,
36597  };
36598 
36600  {
36601  file_descriptor(const std::string& fname, const std::string& access)
36602  : stream_ptr(0),
36603  mode(get_file_mode(access)),
36604  file_name(fname)
36605  {}
36606 
36607  void* stream_ptr;
36609  std::string file_name;
36610 
36611  bool open()
36612  {
36613  if (e_read == mode)
36614  {
36615  std::ifstream* stream = new std::ifstream(file_name.c_str(),std::ios::binary);
36616 
36617  if (!(*stream))
36618  {
36619  file_name.clear();
36620  delete stream;
36621 
36622  return false;
36623  }
36624  else
36625  stream_ptr = stream;
36626 
36627  return true;
36628  }
36629  else if (e_write == mode)
36630  {
36631  std::ofstream* stream = new std::ofstream(file_name.c_str(),std::ios::binary);
36632 
36633  if (!(*stream))
36634  {
36635  file_name.clear();
36636  delete stream;
36637 
36638  return false;
36639  }
36640  else
36641  stream_ptr = stream;
36642 
36643  return true;
36644  }
36645  else if (e_rdwrt == mode)
36646  {
36647  std::fstream* stream = new std::fstream(file_name.c_str(),std::ios::binary);
36648 
36649  if (!(*stream))
36650  {
36651  file_name.clear();
36652  delete stream;
36653 
36654  return false;
36655  }
36656  else
36657  stream_ptr = stream;
36658 
36659  return true;
36660  }
36661  else
36662  return false;
36663  }
36664 
36665  template <typename Stream, typename Ptr>
36666  void close(Ptr& p)
36667  {
36668  Stream* stream = reinterpret_cast<Stream*>(p);
36669  stream->close();
36670  delete stream;
36671  p = reinterpret_cast<Ptr>(0);
36672  }
36673 
36674  bool close()
36675  {
36676  switch (mode)
36677  {
36679  break;
36680 
36682  break;
36683 
36685  break;
36686 
36687  default : return false;
36688  }
36689 
36690  return true;
36691  }
36692 
36693  template <typename View>
36694  bool write(const View& view, const std::size_t amount, const std::size_t offset = 0)
36695  {
36696  switch (mode)
36697  {
36698  case e_write : reinterpret_cast<std::ofstream*>(stream_ptr)->
36699  write(reinterpret_cast<const char*>(view.begin() + offset), amount * sizeof(typename View::value_t));
36700  break;
36701 
36702  case e_rdwrt : reinterpret_cast<std::fstream*>(stream_ptr)->
36703  write(reinterpret_cast<const char*>(view.begin() + offset) , amount * sizeof(typename View::value_t));
36704  break;
36705 
36706  default : return false;
36707  }
36708 
36709  return true;
36710  }
36711 
36712  template <typename View>
36713  bool read(View& view, const std::size_t amount, const std::size_t offset = 0)
36714  {
36715  switch (mode)
36716  {
36717  case e_read : reinterpret_cast<std::ifstream*>(stream_ptr)->
36718  read(reinterpret_cast<char*>(view.begin() + offset), amount * sizeof(typename View::value_t));
36719  break;
36720 
36721  case e_rdwrt : reinterpret_cast<std::fstream*>(stream_ptr)->
36722  read(reinterpret_cast<char*>(view.begin() + offset) , amount * sizeof(typename View::value_t));
36723  break;
36724 
36725  default : return false;
36726  }
36727 
36728  return true;
36729  }
36730 
36731  bool getline(std::string& s)
36732  {
36733  switch (mode)
36734  {
36735  case e_read : return (!!std::getline(*reinterpret_cast<std::ifstream*>(stream_ptr),s));
36736  case e_rdwrt : return (!!std::getline(*reinterpret_cast<std::fstream* >(stream_ptr),s));
36737  default : return false;
36738  }
36739  }
36740 
36741  bool eof()
36742  {
36743  switch (mode)
36744  {
36745  case e_read : return reinterpret_cast<std::ifstream*>(stream_ptr)->eof();
36746  case e_write : return reinterpret_cast<std::ofstream*>(stream_ptr)->eof();
36747  case e_rdwrt : return reinterpret_cast<std::fstream* >(stream_ptr)->eof();
36748  default : return true;
36749  }
36750  }
36751 
36752  file_mode get_file_mode(const std::string& access)
36753  {
36754  if (access.empty() || access.size() > 2)
36755  return e_error;
36756 
36757  std::size_t w_cnt = 0;
36758  std::size_t r_cnt = 0;
36759 
36760  for (std::size_t i = 0; i < access.size(); ++i)
36761  {
36762  switch (std::tolower(access[i]))
36763  {
36764  case 'r' : r_cnt++; break;
36765  case 'w' : w_cnt++; break;
36766  default : return e_error;
36767  }
36768  }
36769 
36770  if ((0 == r_cnt) && (0 == w_cnt))
36771  return e_error;
36772  else if ((r_cnt > 1) || (w_cnt > 1))
36773  return e_error;
36774  else if ((1 == r_cnt) && (1 == w_cnt))
36775  return e_rdwrt;
36776  else if (1 == r_cnt)
36777  return e_read;
36778  else
36779  return e_write;
36780  }
36781  };
36782 
36783  template <typename T>
36785  {
36786  file_descriptor* fd = reinterpret_cast<file_descriptor*>(0);
36787 
36788  std::memcpy(reinterpret_cast<char*>(&fd),
36789  reinterpret_cast<const char*>(&v),
36790  sizeof(fd));
36791  return fd;
36792  }
36793 
36794  template <typename T>
36796  {
36797  #ifdef _MSC_VER
36798  #pragma warning(push)
36799  #pragma warning(disable: 4127)
36800  #endif
36801  if (sizeof(T) < sizeof(void*))
36802  {
36803  throw std::runtime_error("exprtk::rtl::io::file - Error - pointer size larger than holder.");
36804  }
36805  #ifdef _MSC_VER
36806  #pragma warning(pop)
36807  #endif
36808  }
36809 
36810  } // namespace exprtk::rtl::io::file::details
36811 
36812  template <typename T>
36814  {
36815  public:
36816 
36821 
36823 
36825  : exprtk::igeneric_function<T>("S|SS")
36826  { details::perform_check<T>(); }
36827 
36828  inline T operator() (const std::size_t& ps_index, parameter_list_t parameters)
36829  {
36830  std::string file_name;
36831  std::string access;
36832 
36833  file_name = to_str(string_t(parameters[0]));
36834 
36835  if (file_name.empty())
36836  return T(0);
36837 
36838  if (0 == ps_index)
36839  access = "r";
36840  else if (0 == string_t(parameters[1]).size())
36841  return T(0);
36842  else
36843  access = to_str(string_t(parameters[1]));
36844 
36845  details::file_descriptor* fd = new details::file_descriptor(file_name,access);
36846 
36847  if (fd->open())
36848  {
36849  T t = T(0);
36850 
36851  std::memcpy(reinterpret_cast<char*>(&t ),
36852  reinterpret_cast<char*>(&fd),
36853  sizeof(fd));
36854  return t;
36855  }
36856  else
36857  {
36858  delete fd;
36859  return T(0);
36860  }
36861  }
36862  };
36863 
36864  template <typename T>
36865  struct close : public exprtk::ifunction<T>
36866  {
36868 
36870  : exprtk::ifunction<T>(1)
36871  { details::perform_check<T>(); }
36872 
36873  inline T operator() (const T& v)
36874  {
36876 
36877  if (!fd->close())
36878  return T(0);
36879 
36880  delete fd;
36881 
36882  return T(1);
36883  }
36884  };
36885 
36886  template <typename T>
36888  {
36889  public:
36890 
36897 
36899 
36901  : igfun_t("TS|TST|TV|TVT")
36902  { details::perform_check<T>(); }
36903 
36904  inline T operator() (const std::size_t& ps_index, parameter_list_t parameters)
36905  {
36906  details::file_descriptor* fd = details::make_handle(scalar_t(parameters[0])());
36907 
36908  std::size_t amount = 0;
36909 
36910  switch (ps_index)
36911  {
36912  case 0 : {
36913  const string_t buffer(parameters[1]);
36914  amount = buffer.size();
36915  return T(fd->write(buffer,amount) ? 1 : 0);
36916  }
36917 
36918  case 1 : {
36919  const string_t buffer(parameters[1]);
36920  amount = std::min(buffer.size(),
36921  static_cast<std::size_t>(scalar_t(parameters[2])()));
36922  return T(fd->write(buffer,amount) ? 1 : 0);
36923  }
36924 
36925  case 2 : {
36926  const vector_t vec(parameters[1]);
36927  amount = vec.size();
36928  return T(fd->write(vec,amount) ? 1 : 0);
36929  }
36930 
36931  case 3 : {
36932  const vector_t vec(parameters[1]);
36933  amount = std::min(vec.size(),
36934  static_cast<std::size_t>(scalar_t(parameters[2])()));
36935  return T(fd->write(vec,amount) ? 1 : 0);
36936  }
36937  }
36938 
36939  return T(0);
36940  }
36941  };
36942 
36943  template <typename T>
36945  {
36946  public:
36947 
36954 
36956 
36958  : igfun_t("TS|TST|TV|TVT")
36959  { details::perform_check<T>(); }
36960 
36961  inline T operator() (const std::size_t& ps_index, parameter_list_t parameters)
36962  {
36963  details::file_descriptor* fd = details::make_handle(scalar_t(parameters[0])());
36964 
36965  std::size_t amount = 0;
36966 
36967  switch (ps_index)
36968  {
36969  case 0 : {
36970  string_t buffer(parameters[1]);
36971  amount = buffer.size();
36972  return T(fd->read(buffer,amount) ? 1 : 0);
36973  }
36974 
36975  case 1 : {
36976  string_t buffer(parameters[1]);
36977  amount = std::min(buffer.size(),
36978  static_cast<std::size_t>(scalar_t(parameters[2])()));
36979  return T(fd->read(buffer,amount) ? 1 : 0);
36980  }
36981 
36982  case 2 : {
36983  vector_t vec(parameters[1]);
36984  amount = vec.size();
36985  return T(fd->read(vec,amount) ? 1 : 0);
36986  }
36987 
36988  case 3 : {
36989  vector_t vec(parameters[1]);
36990  amount = std::min(vec.size(),
36991  static_cast<std::size_t>(scalar_t(parameters[2])()));
36992  return T(fd->read(vec,amount) ? 1 : 0);
36993  }
36994  }
36995 
36996  return T(0);
36997  }
36998  };
36999 
37000  template <typename T>
37002  {
37003  public:
37004 
37010 
37012 
37014  : igfun_t("T",igfun_t::e_rtrn_string)
37015  { details::perform_check<T>(); }
37016 
37017  inline T operator() (std::string& result,
37018  parameter_list_t parameters)
37019  {
37020  details::file_descriptor* fd = details::make_handle(scalar_t(parameters[0])());
37021  return T(fd->getline(result) ? 1 : 0);
37022  }
37023  };
37024 
37025  template <typename T>
37026  struct eof : public exprtk::ifunction<T>
37027  {
37029 
37031  : exprtk::ifunction<T>(1)
37032  { details::perform_check<T>(); }
37033 
37034  inline T operator() (const T& v)
37035  {
37037 
37038  return (fd->eof() ? T(1) : T(0));
37039  }
37040  };
37041 
37042  template <typename T>
37043  struct package
37044  {
37051 
37053  {
37054  #define exprtk_register_function(FunctionName,FunctionType) \
37055  if (!symtab.add_function(FunctionName,FunctionType)) \
37056  { \
37057  exprtk_debug(( \
37058  "exprtk::rtl::io::file::register_package - Failed to add function: %s\n", \
37059  FunctionName)); \
37060  return false; \
37061  } \
37062 
37063  exprtk_register_function("open" ,o)
37064  exprtk_register_function("close" ,c)
37065  exprtk_register_function("write" ,w)
37066  exprtk_register_function("read" ,r)
37067  exprtk_register_function("getline",g)
37068  exprtk_register_function("eof" ,e)
37069  #undef exprtk_register_function
37070 
37071  return true;
37072  }
37073  };
37074 
37075  } // namespace exprtk::rtl::io::file
37076  } // namespace exprtk::rtl::io
37077  } // namespace exprtk::rtl
37078 } // namespace exprtk
37079 #endif
37080 
37081 #ifndef exprtk_disable_rtl_vecops
37082 namespace exprtk
37083 {
37084  namespace rtl { namespace vecops {
37085 
37086  namespace helper
37087  {
37088  template <typename Vector>
37089  inline bool invalid_range(const Vector& v, const std::size_t r0, const std::size_t r1)
37090  {
37091  if (r0 > (v.size() - 1))
37092  return true;
37093  else if (r1 > (v.size() - 1))
37094  return true;
37095  else if (r1 < r0)
37096  return true;
37097  else
37098  return false;
37099  }
37100 
37101  template <typename T>
37103  {
37109 
37110  static inline bool process(parameter_list_t& parameters,
37111  std::size_t& r0, std::size_t& r1,
37112  const std::size_t& r0_prmidx,
37113  const std::size_t& r1_prmidx,
37114  const std::size_t vec_idx = 0)
37115  {
37116  if (r0_prmidx >= parameters.size())
37117  return false;
37118 
37119  if (r1_prmidx >= parameters.size())
37120  return false;
37121 
37122  if (!scalar_t(parameters[r0_prmidx]).to_uint(r0))
37123  return false;
37124 
37125  if (!scalar_t(parameters[r1_prmidx]).to_uint(r1))
37126  return false;
37127 
37128  return !invalid_range(vector_t(parameters[vec_idx]), r0, r1);
37129  }
37130  };
37131  }
37132 
37133  namespace details
37134  {
37135  template <typename T>
37136  inline void kahan_sum(T& sum, T& error, T v)
37137  {
37138  T x = v - error;
37139  T y = sum + x;
37140  error = (y - sum) - x;
37141  sum = y;
37142  }
37143 
37144  } // namespace exprtk::rtl::details
37145 
37146  template <typename T>
37148  {
37149  public:
37150 
37155 
37157 
37159  : exprtk::igeneric_function<T>("V|VTT")
37160  /*
37161  Overloads:
37162  0. V - vector
37163  1. VTT - vector, r0, r1
37164  */
37165  {}
37166 
37167  inline T operator() (const std::size_t& ps_index, parameter_list_t parameters)
37168  {
37169  const vector_t vec(parameters[0]);
37170 
37171  std::size_t r0 = 0;
37172  std::size_t r1 = vec.size() - 1;
37173 
37174  if (
37175  (1 == ps_index) &&
37176  !helper::load_vector_range<T>::process(parameters, r0, r1, 1, 2, 0)
37177  )
37178  return std::numeric_limits<T>::quiet_NaN();
37179 
37180  for (std::size_t i = r0; i <= r1; ++i)
37181  {
37182  if (vec[i] == T(0))
37183  {
37184  return T(0);
37185  }
37186  }
37187 
37188  return T(1);
37189  }
37190  };
37191 
37192  template <typename T>
37194  {
37195  public:
37196 
37201 
37203 
37205  : exprtk::igeneric_function<T>("V|VTT")
37206  /*
37207  Overloads:
37208  0. V - vector
37209  1. VTT - vector, r0, r1
37210  */
37211  {}
37212 
37213  inline T operator() (const std::size_t& ps_index, parameter_list_t parameters)
37214  {
37215  const vector_t vec(parameters[0]);
37216 
37217  std::size_t r0 = 0;
37218  std::size_t r1 = vec.size() - 1;
37219 
37220  if (
37221  (1 == ps_index) &&
37222  !helper::load_vector_range<T>::process(parameters, r0, r1, 1, 2, 0)
37223  )
37224  return std::numeric_limits<T>::quiet_NaN();
37225 
37226  for (std::size_t i = r0; i <= r1; ++i)
37227  {
37228  if (vec[i] != T(0))
37229  {
37230  return T(0);
37231  }
37232  }
37233 
37234  return T(1);
37235  }
37236  };
37237 
37238  template <typename T>
37240  {
37241  public:
37242 
37247 
37249 
37251  : exprtk::igeneric_function<T>("V|VTT")
37252  /*
37253  Overloads:
37254  0. V - vector
37255  1. VTT - vector, r0, r1
37256  */
37257  {}
37258 
37259  inline T operator() (const std::size_t& ps_index, parameter_list_t parameters)
37260  {
37261  const vector_t vec(parameters[0]);
37262 
37263  std::size_t r0 = 0;
37264  std::size_t r1 = vec.size() - 1;
37265 
37266  if (
37267  (1 == ps_index) &&
37268  !helper::load_vector_range<T>::process(parameters, r0, r1, 1, 2, 0)
37269  )
37270  return std::numeric_limits<T>::quiet_NaN();
37271 
37272  for (std::size_t i = r0; i <= r1; ++i)
37273  {
37274  if (vec[i] != T(0))
37275  {
37276  return T(1);
37277  }
37278  }
37279 
37280  return T(0);
37281  }
37282  };
37283 
37284  template <typename T>
37286  {
37287  public:
37288 
37293 
37295 
37297  : exprtk::igeneric_function<T>("V|VTT")
37298  /*
37299  Overloads:
37300  0. V - vector
37301  1. VTT - vector, r0, r1
37302  */
37303  {}
37304 
37305  inline T operator() (const std::size_t& ps_index, parameter_list_t parameters)
37306  {
37307  const vector_t vec(parameters[0]);
37308 
37309  std::size_t r0 = 0;
37310  std::size_t r1 = vec.size() - 1;
37311 
37312  if (
37313  (1 == ps_index) &&
37314  !helper::load_vector_range<T>::process(parameters, r0, r1, 1, 2, 0)
37315  )
37316  return std::numeric_limits<T>::quiet_NaN();
37317 
37318  for (std::size_t i = r0; i <= r1; ++i)
37319  {
37320  if (vec[i] == T(0))
37321  {
37322  return T(1);
37323  }
37324  }
37325 
37326  return T(0);
37327  }
37328  };
37329 
37330  template <typename T>
37332  {
37333  public:
37334 
37339 
37341 
37343  : exprtk::igeneric_function<T>("V|VTT")
37344  /*
37345  Overloads:
37346  0. V - vector
37347  1. VTT - vector, r0, r1
37348  */
37349  {}
37350 
37351  inline T operator() (const std::size_t& ps_index, parameter_list_t parameters)
37352  {
37353  const vector_t vec(parameters[0]);
37354 
37355  std::size_t r0 = 0;
37356  std::size_t r1 = vec.size() - 1;
37357 
37358  if (
37359  (1 == ps_index) &&
37360  !helper::load_vector_range<T>::process(parameters, r0, r1, 1, 2, 0)
37361  )
37362  return std::numeric_limits<T>::quiet_NaN();
37363 
37364  std::size_t cnt = 0;
37365 
37366  for (std::size_t i = r0; i <= r1; ++i)
37367  {
37368  if (vec[i] != T(0)) ++cnt;
37369  }
37370 
37371  return T(cnt);
37372  }
37373  };
37374 
37375  template <typename T>
37377  {
37378  public:
37379 
37385 
37387 
37389  : exprtk::igeneric_function<T>("VV|VTTVTT")
37390  /*
37391  Overloads:
37392  0. VV - x(vector), y(vector)
37393  1. VTTVTT - x(vector), xr0, xr1, y(vector), yr0, yr1,
37394  */
37395  {}
37396 
37397  inline T operator() (const std::size_t& ps_index, parameter_list_t parameters)
37398  {
37399  const vector_t x(parameters[0]);
37400  vector_t y(parameters[(0 == ps_index) ? 1 : 3]);
37401 
37402  std::size_t xr0 = 0;
37403  std::size_t xr1 = x.size() - 1;
37404 
37405  std::size_t yr0 = 0;
37406  std::size_t yr1 = y.size() - 1;
37407 
37408  if (1 == ps_index)
37409  {
37410  if (
37411  !helper::load_vector_range<T>::process(parameters, xr0, xr1, 1, 2, 0) ||
37412  !helper::load_vector_range<T>::process(parameters, yr0, yr1, 4, 5, 3)
37413  )
37414  return T(0);
37415  }
37416 
37417  const std::size_t n = std::min(xr1 - xr0 + 1, yr1 - yr0 + 1);
37418 
37419  std::copy(x.begin() + xr0, x.begin() + xr0 + n, y.begin() + yr0);
37420 
37421  return T(n);
37422  }
37423  };
37424 
37425  template <typename T>
37426  class rol : public exprtk::igeneric_function<T>
37427  {
37428  public:
37429 
37435 
37437 
37439  : exprtk::igeneric_function<T>("VT|VTTT")
37440  /*
37441  Overloads:
37442  0. VT - vector, N
37443  1. VTTT - vector, N, r0, r1
37444  */
37445  {}
37446 
37447  inline T operator() (const std::size_t& ps_index, parameter_list_t parameters)
37448  {
37449  vector_t vec(parameters[0]);
37450 
37451  std::size_t n = 0;
37452  std::size_t r0 = 0;
37453  std::size_t r1 = vec.size() - 1;
37454 
37455  if (!scalar_t(parameters[1]).to_uint(n))
37456  return T(0);
37457 
37458  if (
37459  (1 == ps_index) &&
37460  !helper::load_vector_range<T>::process(parameters, r0, r1, 2, 3, 0)
37461  )
37462  return T(0);
37463 
37464  std::size_t dist = r1 - r0 + 1;
37465  std::size_t shift = n % dist;
37466 
37467  std::rotate(vec.begin() + r0, vec.begin() + r0 + shift, vec.begin() + r1 + 1);
37468 
37469  return T(1);
37470  }
37471  };
37472 
37473  template <typename T>
37474  class ror : public exprtk::igeneric_function<T>
37475  {
37476  public:
37477 
37483 
37485 
37487  : exprtk::igeneric_function<T>("VT|VTTT")
37488  /*
37489  Overloads:
37490  0. VT - vector, N
37491  1. VTTT - vector, N, r0, r1
37492  */
37493  {}
37494 
37495  inline T operator() (const std::size_t& ps_index, parameter_list_t parameters)
37496  {
37497  vector_t vec(parameters[0]);
37498 
37499  std::size_t n = 0;
37500  std::size_t r0 = 0;
37501  std::size_t r1 = vec.size() - 1;
37502 
37503  if (!scalar_t(parameters[1]).to_uint(n))
37504  return T(0);
37505 
37506  if (
37507  (1 == ps_index) &&
37508  !helper::load_vector_range<T>::process(parameters, r0, r1, 2, 3, 0)
37509  )
37510  return T(0);
37511 
37512  std::size_t dist = r1 - r0 + 1;
37513  std::size_t shift = (dist - (n % dist)) % dist;
37514 
37515  std::rotate(vec.begin() + r0, vec.begin() + r0 + shift, vec.begin() + r1 + 1);
37516 
37517  return T(1);
37518  }
37519  };
37520 
37521  template <typename T>
37523  {
37524  public:
37525 
37531 
37533 
37535  : exprtk::igeneric_function<T>("VT|VTTT")
37536  /*
37537  Overloads:
37538  0. VT - vector, N
37539  1. VTTT - vector, N, r0, r1
37540  */
37541  {}
37542 
37543  inline T operator() (const std::size_t& ps_index, parameter_list_t parameters)
37544  {
37545  vector_t vec(parameters[0]);
37546 
37547  std::size_t n = 0;
37548  std::size_t r0 = 0;
37549  std::size_t r1 = vec.size() - 1;
37550 
37551  if (!scalar_t(parameters[1]).to_uint(n))
37552  return T(0);
37553 
37554  if (
37555  (1 == ps_index) &&
37556  !helper::load_vector_range<T>::process(parameters, r0, r1, 2, 3, 0)
37557  )
37558  return T(0);
37559 
37560  std::size_t dist = r1 - r0 + 1;
37561 
37562  if (n > dist)
37563  return T(0);
37564 
37565  std::rotate(vec.begin() + r0, vec.begin() + r0 + n, vec.begin() + r1 + 1);
37566 
37567  for (std::size_t i = r1 - n + 1; i <= r1; ++i)
37568  {
37569  vec[i] = T(0);
37570  }
37571 
37572  return T(1);
37573  }
37574  };
37575 
37576  template <typename T>
37578  {
37579  public:
37580 
37586 
37588 
37590  : exprtk::igeneric_function<T>("VT|VTTT")
37591  /*
37592  Overloads:
37593  0. VT - vector, N
37594  1. VTTT - vector, N, r0, r1
37595  */
37596  {}
37597 
37598  inline T operator() (const std::size_t& ps_index, parameter_list_t parameters)
37599  {
37600  vector_t vec(parameters[0]);
37601 
37602  std::size_t n = 0;
37603  std::size_t r0 = 0;
37604  std::size_t r1 = vec.size() - 1;
37605 
37606  if (!scalar_t(parameters[1]).to_uint(n))
37607  return T(0);
37608 
37609  if (
37610  (1 == ps_index) &&
37611  !helper::load_vector_range<T>::process(parameters, r0, r1, 2, 3, 0)
37612  )
37613  return T(0);
37614 
37615  std::size_t dist = r1 - r0 + 1;
37616 
37617  if (n > dist)
37618  return T(0);
37619 
37620  std::size_t shift = (dist - (n % dist)) % dist;
37621 
37622  std::rotate(vec.begin() + r0, vec.begin() + r0 + shift, vec.begin() + r1 + 1);
37623 
37624  for (std::size_t i = r0; i < r0 + n; ++i)
37625  {
37626  vec[i] = T(0);
37627  }
37628 
37629  return T(1);
37630  }
37631  };
37632 
37633  template <typename T>
37635  {
37636  public:
37637 
37643 
37645 
37647  : exprtk::igeneric_function<T>("V|VTT|VS|VSTT")
37648  /*
37649  Overloads:
37650  0. V - vector
37651  1. VTT - vector, r0, r1
37652  2. VS - vector, string
37653  3. VSTT - vector, string, r0, r1
37654  */
37655  {}
37656 
37657  inline T operator() (const std::size_t& ps_index, parameter_list_t parameters)
37658  {
37659  vector_t vec(parameters[0]);
37660 
37661  std::size_t r0 = 0;
37662  std::size_t r1 = vec.size() - 1;
37663 
37664  if ((1 == ps_index) && !helper::load_vector_range<T>::process(parameters, r0, r1, 1, 2, 0))
37665  return T(0);
37666  if ((3 == ps_index) && !helper::load_vector_range<T>::process(parameters, r0, r1, 2, 3, 0))
37667  return T(0);
37668 
37669  bool ascending = true;
37670 
37671  if ((2 == ps_index) || (3 == ps_index))
37672  {
37673  if (exprtk::details::imatch(to_str(string_t(parameters[1])),"ascending"))
37674  ascending = true;
37675  else if (exprtk::details::imatch(to_str(string_t(parameters[1])),"descending"))
37676  ascending = false;
37677  else
37678  return T(0);
37679  }
37680 
37681  if (ascending)
37682  std::sort(vec.begin() + r0, vec.begin() + r1 + 1, std::less<T> ());
37683  else
37684  std::sort(vec.begin() + r0, vec.begin() + r1 + 1, std::greater<T>());
37685 
37686  return T(1);
37687  }
37688  };
37689 
37690  template <typename T>
37692  {
37693  public:
37694 
37700 
37702 
37704  : exprtk::igeneric_function<T>("VT|VTTT")
37705  /*
37706  Overloads:
37707  0. VT - vector, nth-element
37708  1. VTTT - vector, nth-element, r0, r1
37709  */
37710  {}
37711 
37712  inline T operator() (const std::size_t& ps_index, parameter_list_t parameters)
37713  {
37714  vector_t vec(parameters[0]);
37715 
37716  std::size_t n = 0;
37717  std::size_t r0 = 0;
37718  std::size_t r1 = vec.size() - 1;
37719 
37720  if (!scalar_t(parameters[1]).to_uint(n))
37721  return T(0);
37722 
37723  if ((1 == ps_index) && !helper::load_vector_range<T>::process(parameters, r0, r1, 2, 3, 0))
37724  return std::numeric_limits<T>::quiet_NaN();
37725 
37726  std::nth_element(vec.begin() + r0, vec.begin() + r0 + n , vec.begin() + r1 + 1);
37727 
37728  return T(1);
37729  }
37730  };
37731 
37732  template <typename T>
37734  {
37735  public:
37736 
37742 
37744 
37746  : exprtk::igeneric_function<T>("VT|VTT|VTTT|VTTTT")
37747  /*
37748  Overloads:
37749  0. VT - vector, increment
37750  1. VTT - vector, increment, base
37751  2. VTTTT - vector, increment, r0, r1
37752  3. VTTTT - vector, increment, base, r0, r1
37753  */
37754  {}
37755 
37756  inline T operator() (const std::size_t& ps_index, parameter_list_t parameters)
37757  {
37758  vector_t vec(parameters[0]);
37759 
37760  T increment = scalar_t(parameters[1])();
37761  T base = ((1 == ps_index) || (3 == ps_index)) ? scalar_t(parameters[2])() : T(0);
37762 
37763  std::size_t r0 = 0;
37764  std::size_t r1 = vec.size() - 1;
37765 
37766  if ((2 == ps_index) && !helper::load_vector_range<T>::process(parameters, r0, r1, 2, 3, 0))
37767  return std::numeric_limits<T>::quiet_NaN();
37768  else if ((3 == ps_index) && !helper::load_vector_range<T>::process(parameters, r0, r1, 3, 4, 0))
37769  return std::numeric_limits<T>::quiet_NaN();
37770  else
37771  {
37772  long long j = 0;
37773 
37774  for (std::size_t i = r0; i <= r1; ++i, ++j)
37775  {
37776  vec[i] = base + (increment * j);
37777  }
37778  }
37779 
37780  return T(1);
37781  }
37782  };
37783 
37784  template <typename T>
37786  {
37787  public:
37788 
37793 
37795 
37797  : exprtk::igeneric_function<T>("V|VTT")
37798  /*
37799  Overloads:
37800  0. V - vector
37801  1. VTT - vector, r0, r1
37802  */
37803  {}
37804 
37805  inline T operator() (const std::size_t& ps_index, parameter_list_t parameters)
37806  {
37807  const vector_t vec(parameters[0]);
37808 
37809  std::size_t r0 = 0;
37810  std::size_t r1 = vec.size() - 1;
37811 
37812  if ((1 == ps_index) && !helper::load_vector_range<T>::process(parameters, r0, r1, 1, 2, 0))
37813  return std::numeric_limits<T>::quiet_NaN();
37814 
37815  T result = T(0);
37816  T error = T(0);
37817 
37818  for (std::size_t i = r0; i <= r1; ++i)
37819  {
37820  details::kahan_sum(result, error, vec[i]);
37821  }
37822 
37823  return result;
37824  }
37825  };
37826 
37827  template <typename T>
37829  {
37830  public:
37831 
37837 
37839 
37841  : exprtk::igeneric_function<T>("TVV|TVVTT")
37842  /*
37843  y <- ax + y
37844  Overloads:
37845  0. TVV - a, x(vector), y(vector)
37846  1. TVVTT - a, x(vector), y(vector), r0, r1
37847  */
37848  {}
37849 
37850  inline T operator() (const std::size_t& ps_index, parameter_list_t parameters)
37851  {
37852  const vector_t x(parameters[1]);
37853  vector_t y(parameters[2]);
37854 
37855  std::size_t r0 = 0;
37856  std::size_t r1 = std::min(x.size(),y.size()) - 1;
37857 
37858  if ((1 == ps_index) && !helper::load_vector_range<T>::process(parameters, r0, r1, 3, 4, 1))
37859  return std::numeric_limits<T>::quiet_NaN();
37860  else if (helper::invalid_range(y, r0, r1))
37861  return std::numeric_limits<T>::quiet_NaN();
37862 
37863  T a = scalar_t(parameters[0])();
37864 
37865  for (std::size_t i = r0; i <= r1; ++i)
37866  {
37867  y[i] = (a * x[i]) + y[i];
37868  }
37869 
37870  return T(1);
37871  }
37872  };
37873 
37874  template <typename T>
37876  {
37877  public:
37878 
37884 
37886 
37888  : exprtk::igeneric_function<T>("TVTV|TVTVTT")
37889  /*
37890  y <- ax + by
37891  Overloads:
37892  0. TVTV - a, x(vector), b, y(vector)
37893  1. TVTVTT - a, x(vector), b, y(vector), r0, r1
37894  */
37895  {}
37896 
37897  inline T operator() (const std::size_t& ps_index, parameter_list_t parameters)
37898  {
37899  const vector_t x(parameters[1]);
37900  vector_t y(parameters[3]);
37901 
37902  std::size_t r0 = 0;
37903  std::size_t r1 = std::min(x.size(),y.size()) - 1;
37904 
37905  if ((1 == ps_index) && !helper::load_vector_range<T>::process(parameters, r0, r1, 4, 5, 1))
37906  return std::numeric_limits<T>::quiet_NaN();
37907  else if (helper::invalid_range(y, r0, r1))
37908  return std::numeric_limits<T>::quiet_NaN();
37909 
37910  const T a = scalar_t(parameters[0])();
37911  const T b = scalar_t(parameters[2])();
37912 
37913  for (std::size_t i = r0; i <= r1; ++i)
37914  {
37915  y[i] = (a * x[i]) + (b * y[i]);
37916  }
37917 
37918  return T(1);
37919  }
37920  };
37921 
37922  template <typename T>
37924  {
37925  public:
37926 
37932 
37934 
37936  : exprtk::igeneric_function<T>("TVVV|TVVVTT")
37937  /*
37938  z <- ax + y
37939  Overloads:
37940  0. TVVV - a, x(vector), y(vector), z(vector)
37941  1. TVVVTT - a, x(vector), y(vector), z(vector), r0, r1
37942  */
37943  {}
37944 
37945  inline T operator() (const std::size_t& ps_index, parameter_list_t parameters)
37946  {
37947  const vector_t x(parameters[1]);
37948  const vector_t y(parameters[2]);
37949  vector_t z(parameters[3]);
37950 
37951  std::size_t r0 = 0;
37952  std::size_t r1 = std::min(x.size(),y.size()) - 1;
37953 
37954  if ((1 == ps_index) && !helper::load_vector_range<T>::process(parameters, r0, r1, 3, 4, 1))
37955  return std::numeric_limits<T>::quiet_NaN();
37956  else if (helper::invalid_range(y, r0, r1))
37957  return std::numeric_limits<T>::quiet_NaN();
37958  else if (helper::invalid_range(z, r0, r1))
37959  return std::numeric_limits<T>::quiet_NaN();
37960 
37961  T a = scalar_t(parameters[0])();
37962 
37963  for (std::size_t i = r0; i <= r1; ++i)
37964  {
37965  z[i] = (a * x[i]) + y[i];
37966  }
37967 
37968  return T(1);
37969  }
37970  };
37971 
37972  template <typename T>
37974  {
37975  public:
37976 
37982 
37984 
37986  : exprtk::igeneric_function<T>("TVTVV|TVTVVTT")
37987  /*
37988  z <- ax + by
37989  Overloads:
37990  0. TVTVV - a, x(vector), b, y(vector), z(vector)
37991  1. TVTVVTT - a, x(vector), b, y(vector), z(vector), r0, r1
37992  */
37993  {}
37994 
37995  inline T operator() (const std::size_t& ps_index, parameter_list_t parameters)
37996  {
37997  const vector_t x(parameters[1]);
37998  const vector_t y(parameters[3]);
37999  vector_t z(parameters[4]);
38000 
38001  std::size_t r0 = 0;
38002  std::size_t r1 = std::min(x.size(),y.size()) - 1;
38003 
38004  if ((1 == ps_index) && !helper::load_vector_range<T>::process(parameters, r0, r1, 4, 5, 1))
38005  return std::numeric_limits<T>::quiet_NaN();
38006  else if (helper::invalid_range(y, r0, r1))
38007  return std::numeric_limits<T>::quiet_NaN();
38008  else if (helper::invalid_range(z, r0, r1))
38009  return std::numeric_limits<T>::quiet_NaN();
38010 
38011  const T a = scalar_t(parameters[0])();
38012  const T b = scalar_t(parameters[2])();
38013 
38014  for (std::size_t i = r0; i <= r1; ++i)
38015  {
38016  z[i] = (a * x[i]) + (b * y[i]);
38017  }
38018 
38019  return T(1);
38020  }
38021  };
38022 
38023  template <typename T>
38025  {
38026  public:
38027 
38033 
38035 
38037  : exprtk::igeneric_function<T>("TVTV|TVTVTT")
38038  /*
38039  z <- ax + b
38040  Overloads:
38041  0. TVTV - a, x(vector), b, z(vector)
38042  1. TVTVTT - a, x(vector), b, z(vector), r0, r1
38043  */
38044  {}
38045 
38046  inline T operator() (const std::size_t& ps_index, parameter_list_t parameters)
38047  {
38048  const vector_t x(parameters[1]);
38049  vector_t z(parameters[3]);
38050 
38051  std::size_t r0 = 0;
38052  std::size_t r1 = x.size() - 1;
38053 
38054  if ((1 == ps_index) && !helper::load_vector_range<T>::process(parameters, r0, r1, 4, 5, 1))
38055  return std::numeric_limits<T>::quiet_NaN();
38056  else if (helper::invalid_range(z, r0, r1))
38057  return std::numeric_limits<T>::quiet_NaN();
38058 
38059  const T a = scalar_t(parameters[0])();
38060  const T b = scalar_t(parameters[2])();
38061 
38062  for (std::size_t i = r0; i <= r1; ++i)
38063  {
38064  z[i] = (a * x[i]) + b;
38065  }
38066 
38067  return T(1);
38068  }
38069  };
38070 
38071  template <typename T>
38072  class dot : public exprtk::igeneric_function<T>
38073  {
38074  public:
38075 
38081 
38083 
38085  : exprtk::igeneric_function<T>("VV|VVTT")
38086  /*
38087  Overloads:
38088  0. VV - x(vector), y(vector)
38089  1. VVTT - x(vector), y(vector), r0, r1
38090  */
38091  {}
38092 
38093  inline T operator() (const std::size_t& ps_index, parameter_list_t parameters)
38094  {
38095  const vector_t x(parameters[0]);
38096  const vector_t y(parameters[1]);
38097 
38098  std::size_t r0 = 0;
38099  std::size_t r1 = std::min(x.size(),y.size()) - 1;
38100 
38101  if ((1 == ps_index) && !helper::load_vector_range<T>::process(parameters, r0, r1, 2, 3, 0))
38102  return std::numeric_limits<T>::quiet_NaN();
38103  else if (helper::invalid_range(y, r0, r1))
38104  return std::numeric_limits<T>::quiet_NaN();
38105 
38106  T result = T(0);
38107 
38108  for (std::size_t i = r0; i <= r1; ++i)
38109  {
38110  result += (x[i] * y[i]);
38111  }
38112 
38113  return result;
38114  }
38115  };
38116 
38117  template <typename T>
38119  {
38120  public:
38121 
38127 
38129 
38131  : exprtk::igeneric_function<T>("VV|VVTT")
38132  /*
38133  Overloads:
38134  0. VV - x(vector), y(vector)
38135  1. VVTT - x(vector), y(vector), r0, r1
38136  */
38137  {}
38138 
38139  inline T operator() (const std::size_t& ps_index, parameter_list_t parameters)
38140  {
38141  const vector_t x(parameters[0]);
38142  const vector_t y(parameters[1]);
38143 
38144  std::size_t r0 = 0;
38145  std::size_t r1 = std::min(x.size(),y.size()) - 1;
38146 
38147  if ((1 == ps_index) && !helper::load_vector_range<T>::process(parameters, r0, r1, 2, 3, 0))
38148  return std::numeric_limits<T>::quiet_NaN();
38149  else if (helper::invalid_range(y, r0, r1))
38150  return std::numeric_limits<T>::quiet_NaN();
38151 
38152  T result = T(0);
38153  T error = T(0);
38154 
38155  for (std::size_t i = r0; i <= r1; ++i)
38156  {
38157  details::kahan_sum(result, error, (x[i] * y[i]));
38158  }
38159 
38160  return result;
38161  }
38162  };
38163 
38164  template <typename T>
38165  struct package
38166  {
38188 
38190  {
38191  #define exprtk_register_function(FunctionName,FunctionType) \
38192  if (!symtab.add_function(FunctionName,FunctionType)) \
38193  { \
38194  exprtk_debug(( \
38195  "exprtk::rtl::vecops::register_package - Failed to add function: %s\n", \
38196  FunctionName)); \
38197  return false; \
38198  } \
38199 
38200  exprtk_register_function("all_true" ,at)
38201  exprtk_register_function("all_false" ,af)
38202  exprtk_register_function("any_true" ,nt)
38203  exprtk_register_function("any_false" ,nf)
38204  exprtk_register_function("count" , c)
38205  exprtk_register_function("copy" , cp)
38206  exprtk_register_function("rotate_left" ,rl)
38208  exprtk_register_function("rotate_right" ,rr)
38210  exprtk_register_function("shftl" ,sl)
38211  exprtk_register_function("shftr" ,sr)
38212  exprtk_register_function("sort" ,st)
38213  exprtk_register_function("nth_element" ,ne)
38214  exprtk_register_function("iota" ,ia)
38215  exprtk_register_function("sumk" ,sk)
38222  exprtk_register_function("dotk" ,dtk)
38223  #undef exprtk_register_function
38224 
38225  return true;
38226  }
38227  };
38228 
38229  } // namespace exprtk::rtl::vecops
38230  } // namespace exprtk::rtl
38231 } // namespace exprtk
38232 #endif
38233 
38234 namespace exprtk
38235 {
38236  namespace information
38237  {
38238  static const char* library = "Mathematical Expression Toolkit";
38239  static const char* version = "2.718281828459045235360287471352662497757247093699"
38240  "95957496696762772407663035354759457138217852516642";
38241  static const char* date = "20180913";
38242 
38243  static inline std::string data()
38244  {
38245  static const std::string info_str = std::string(library) +
38246  std::string(" v") + std::string(version) +
38247  std::string(" (") + date + std::string(")");
38248  return info_str;
38249  }
38250 
38251  } // namespace information
38252 
38253  #ifdef exprtk_debug
38254  #undef exprtk_debug
38255  #endif
38256 
38257  #ifdef exprtk_error_location
38258  #undef exprtk_error_location
38259  #endif
38260 
38261  #ifdef exprtk_disable_fallthrough_begin
38262  #undef exprtk_disable_fallthrough_begin
38263  #endif
38264 
38265  #ifdef exprtk_disable_fallthrough_end
38266  #undef exprtk_disable_fallthrough_end
38267  #endif
38268 
38269 } // namespace exprtk
38270 
38271 #endif
static expression_node_ptr process(expression_generator< Type > &expr_gen, const details::operator_type &operation, expression_node_ptr(&branch)[2])
Definition: exprtk.hpp:29660
static T process(Type t1, Type t2)
Definition: exprtk.hpp:12008
static std::string id(expression_generator< Type > &expr_gen, const details::operator_type o0, const details::operator_type o1, const details::operator_type o2)
Definition: exprtk.hpp:32075
expression_node_ptr synthesize_sosr_expression(const details::operator_type &opr, expression_node_ptr(&branch)[2])
Definition: exprtk.hpp:33760
virtual char_cptr base() const =0
Definition: exprtk.hpp:4413
generic_type::vector_view vector_t
Definition: exprtk.hpp:37931
iota()
Definition: exprtk.hpp:37745
static expression_node_ptr process(expression_generator< Type > &expr_gen, const details::operator_type &operation, expression_node_ptr(&branch)[2])
Definition: exprtk.hpp:29133
ff04_functor f
Definition: exprtk.hpp:16070
generic_type::vector_view vector_t
Definition: exprtk.hpp:38126
bool collect_variables(const std::string &expr_str, Sequence< std::string, Allocator > &symbol_list)
Definition: exprtk.hpp:34689
Definition: exprtk.hpp:4423
static expression_node_ptr process(expression_generator< Type > &expr_gen, const details::operator_type &operation, expression_node_ptr(&branch)[2])
Definition: exprtk.hpp:30758
Definition: exprtk.hpp:13130
range_t range_
Definition: exprtk.hpp:8843
generic_type::string_view string_t
Definition: exprtk.hpp:37008
static std::pair< bool, vector_t * > make(std::deque< T, Allocator > &v, const bool is_const=false)
Definition: exprtk.hpp:16324
const bfunc_t f_
Definition: exprtk.hpp:13385
bool is_stringvar(const std::string &stringvar_name) const
Definition: exprtk.hpp:18832
static std::string id()
Definition: exprtk.hpp:14195
expression_node< T >::node_type type() const
Definition: exprtk.hpp:6338
Definition: exprtk.hpp:5510
ff03_functor f
Definition: exprtk.hpp:16060
bool initialised_
Definition: exprtk.hpp:10504
str_base_ptr str_base_ptr_
Definition: exprtk.hpp:8309
static T process_2(const Sequence &arg_list)
Definition: exprtk.hpp:12678
T value() const
Definition: exprtk.hpp:6124
settings_inequality_opr
Definition: exprtk.hpp:19302
settings_store & disable_inequality_operation(settings_inequality_opr inequality)
Definition: exprtk.hpp:19606
Definition: exprtk.hpp:2862
static std::string id()
Definition: exprtk.hpp:14278
expression_node< T >::node_type type() const
Definition: exprtk.hpp:5449
std::string assign_opr_to_string(details::operator_type opr)
Definition: exprtk.hpp:19746
bool token_is(const token_t::token_type &ttype, const token_advance_mode mode=e_advance)
Definition: exprtk.hpp:4016
opr_base< T >::Type Type
Definition: exprtk.hpp:12082
Definition: exprtk.hpp:4436
Definition: exprtk.hpp:35779
expression_node_ptr synthesize_null_expression(const details::operator_type &operation, expression_node_ptr(&branch)[2])
Definition: exprtk.hpp:34188
details::node_allocator node_allocator_
Definition: exprtk.hpp:34654
vovocov_t::sf4_type sf4_type
Definition: exprtk.hpp:31749
scoped_deq_delete(parser< T > &pr, std::deque< ptr_t > &deq)
Definition: exprtk.hpp:20752
static T_ execute(ifunction &f, T_(&v)[9])
Definition: exprtk.hpp:11239
bool compute(const std::string &expression_string, T &result)
Definition: exprtk.hpp:35041
void clear_functions()
Definition: exprtk.hpp:16745
bool update_error(type &error, const std::string &expression)
Definition: exprtk.hpp:18037
bipowninv_node< T, PowOp > & operator=(const bipowninv_node< T, PowOp > &)
expression_ptr condition_
Definition: exprtk.hpp:6411
bool var_range()
Definition: exprtk.hpp:6882
bool invalid_state_
Definition: exprtk.hpp:23316
std::string name
Definition: exprtk.hpp:18297
operator_type operation() const
Definition: exprtk.hpp:14738
static expression_node< T >::node_type type()
Definition: exprtk.hpp:12151
const vds_t & vds() const
Definition: exprtk.hpp:10957
expression_node< T >::node_type type() const
Definition: exprtk.hpp:8058
Definition: exprtk.hpp:4909
covoc_t::type1 node_type
Definition: exprtk.hpp:30011
std::string type_id() const
Definition: exprtk.hpp:14089
void register_symbol_table(symbol_table< T > &st)
Definition: exprtk.hpp:17777
vector_holder_t & vec_holder()
Definition: exprtk.hpp:7174
T operator()(const std::size_t &ps_index, parameter_list_t parameters)
Definition: exprtk.hpp:37657
node_type & operator=(node_type &)
Definition: exprtk.hpp:14110
T0 t0_
Definition: exprtk.hpp:13751
static T process(const T &t0, const T &t1, const T &t2, const T &t3, const bfunc_t bf0, const bfunc_t bf1, const bfunc_t bf2)
Definition: exprtk.hpp:13532
static std::string id(expression_generator< Type > &expr_gen, const details::operator_type o0, const details::operator_type o1, const details::operator_type o2)
Definition: exprtk.hpp:32655
const std::size_t param_seq_index_
Definition: exprtk.hpp:11775
Definition: exprtk.hpp:9384
bool is_operator_char(const char_t c)
Definition: exprtk.hpp:101
T compute_pow10(T d, const int exponent)
Definition: exprtk.hpp:1618
expression_node< typename node_type::value_type > * allocate_type(T1 t1, T2 t2, T3 t3, T4 t4) const
Definition: exprtk.hpp:15644
void dump_error(const type &error)
Definition: exprtk.hpp:18079
generic_type::scalar_view scalar_t
Definition: exprtk.hpp:37584
expression(const symbol_table< T > &symbol_table)
Definition: exprtk.hpp:17700
Definition: exprtk.hpp:1362
Definition: exprtk.hpp:2028
vector_interface< T > * ivector_ptr
Definition: exprtk.hpp:13072
bool is_unary_node(const expression_node< T > *node)
Definition: exprtk.hpp:4997
ivararg_function< T > ivararg_function_t
Definition: exprtk.hpp:18127
T operator()(const std::size_t &ps_index, parameter_list_t parameters)
Definition: exprtk.hpp:37712
Definition: exprtk.hpp:14043
static std::size_t min_size(control_block *cb0, control_block *cb1)
Definition: exprtk.hpp:4731
virtual bool join(const token &, const token &, const token &, token &)
Definition: exprtk.hpp:3096
Definition: exprtk.hpp:4399
static expression_node_ptr process(expression_generator< Type > &expr_gen, const details::operator_type &operation, expression_node_ptr(&branch)[2])
Definition: exprtk.hpp:29600
int v
Definition: obj.cpp:19
details::T0oT1oT2oT3_define< T, const_t, cref_t, const_t, cref_t > covocov_t
Definition: exprtk.hpp:18216
std::string & s0()
Definition: exprtk.hpp:15105
Definition: exprtk.hpp:4433
Definition: exprtk.hpp:17970
T0 t0() const
Definition: exprtk.hpp:14253
expression_node_ptr const_optimise_sf4(const details::operator_type &operation, expression_node_ptr(&branch)[4])
Definition: exprtk.hpp:26939
static expression_node< T >::node_type type()
Definition: exprtk.hpp:12199
virtual ~sosos_base_node()
Definition: exprtk.hpp:13244
const vds_t & vds() const
Definition: exprtk.hpp:10306
static expression_node_ptr process(expression_generator< Type > &expr_gen, const details::operator_type &operation, expression_node_ptr(&branch)[2])
Definition: exprtk.hpp:30674
bool disable_zero_return_
Definition: exprtk.hpp:19801
SType2 s2_
Definition: exprtk.hpp:15124
expression_node< T >::node_type type() const
Definition: exprtk.hpp:5860
expression_node_ptr conditional_string(expression_node_ptr condition, expression_node_ptr consequent, expression_node_ptr alternative) const
Definition: exprtk.hpp:26353
vector_node_ptr vec()
Definition: exprtk.hpp:10473
static T result(T v)
Definition: exprtk.hpp:1556
static bool compile_right(expression_generator< Type > &expr_gen, ExternalType t, const details::operator_type &operation, expression_node_ptr &sf3node, expression_node_ptr &result)
Definition: exprtk.hpp:29286
type_store< T > generic_type
Definition: exprtk.hpp:15959
std::stack< std::pair< char, std::size_t > > stack_
Definition: exprtk.hpp:3486
expression_node< T > * expression_ptr
Definition: exprtk.hpp:14719
T value() const
Definition: exprtk.hpp:13871
Definition: exprtk.hpp:4456
Definition: exprtk.hpp:9430
bool operator()(const lexer::token &t)
Definition: exprtk.hpp:3512
generic_type::scalar_view scalar_t
Definition: exprtk.hpp:37009
static T_ execute(ifunction &f, T_(&v)[12])
Definition: exprtk.hpp:11218
bool is_continue_node(const expression_node< T > *node)
Definition: exprtk.hpp:5099
control_block(expression_ptr e)
Definition: exprtk.hpp:17607
vector_interface< T > * ivector_ptr
Definition: exprtk.hpp:12833
std::string substr(const std::size_t &begin, const std::size_t &end)
Definition: exprtk.hpp:2313
sf3_var_node(const T &v0, const T &v1, const T &v2)
Definition: exprtk.hpp:9262
opr_base< T >::Type Type
Definition: exprtk.hpp:11982
static expression_node_ptr process(expression_generator< Type > &expr_gen, const details::operator_type &operation, expression_node_ptr(&branch)[2])
Definition: exprtk.hpp:28894
bool is_end(details::char_cptr itr)
Definition: exprtk.hpp:2333
Definition: exprtk.hpp:12174
set_t invalid_comb_
Definition: exprtk.hpp:3787
static expression_node_ptr process(expression_generator< Type > &expr_gen, const details::operator_type &operation, expression_node_ptr(&branch)[2])
Definition: exprtk.hpp:31811
axpby()
Definition: exprtk.hpp:37887
static std::string id()
Definition: exprtk.hpp:13821
Definition: exprtk.hpp:2024
static T result(T v)
Definition: exprtk.hpp:1554
std::size_t ip_index
Definition: exprtk.hpp:18302
expression_node_ptr synthesize_csrocsr_expression(const details::operator_type &opr, expression_node_ptr(&branch)[2])
Definition: exprtk.hpp:33953
Definition: exprtk.hpp:2027
igfun_t::generic_type generic_type
Definition: exprtk.hpp:37291
static expression_node< T >::node_type type()
Definition: exprtk.hpp:12142
const range_t & range_ref() const
Definition: exprtk.hpp:8962
T value() const
Definition: exprtk.hpp:11377
std::vector< unsigned char > delete_branch_
Definition: exprtk.hpp:9380
bool wc_imatch(const std::string &wild_card, const std::string &str)
Definition: exprtk.hpp:643
expression_node_t * expression_node_ptr
Definition: exprtk.hpp:18317
stringvar_node()
Definition: exprtk.hpp:7492
range_t rp_
Definition: exprtk.hpp:5644
static T process_1(const Sequence &arg_list)
Definition: exprtk.hpp:12671
operator_type operation_
Definition: exprtk.hpp:5936
static void assign(RefType t1, Type t2)
Definition: exprtk.hpp:12010
std::set< std::string, details::ilesscompare > ignore_set_
Definition: exprtk.hpp:3229
vec_data_store(const std::size_t &size)
Definition: exprtk.hpp:4638
expression_node_ptr parse_define_string_statement(const std::string &str_name, expression_node_ptr initialisation_expression)
Definition: exprtk.hpp:24076
expression_node< T >::node_type type() const
Definition: exprtk.hpp:13962
expression_node_ptr synthesize_csrosr_expression(const details::operator_type &opr, expression_node_ptr(&branch)[2])
Definition: exprtk.hpp:33924
const T c_
Definition: exprtk.hpp:14483
virtual void init()
Definition: exprtk.hpp:2855
#define register_unary_op(Op, UnaryFunctor)
vovoc_t::sf3_type sf3_type
Definition: exprtk.hpp:29537
static T result(T v)
Definition: exprtk.hpp:1558
int remainder
Definition: exprtk.hpp:4520
Definition: exprtk.hpp:4412
details::assignment_rebasevec_elem_node< T > assignment_rebasevec_elem_node_t
Definition: exprtk.hpp:18166
token_t eof_token_
Definition: exprtk.hpp:2840
settings_store & disable_logic_operation(settings_logic_opr logic)
Definition: exprtk.hpp:19567
expression_node< T > * expression_ptr
Definition: exprtk.hpp:9638
symbol_table_t::function_ptr function_ptr
Definition: exprtk.hpp:18551
vds_t & vds()
Definition: exprtk.hpp:9883
std::string & s1()
Definition: exprtk.hpp:14810
void parse_hex(Iterator &itr, Iterator end, std::string::value_type &result)
Definition: exprtk.hpp:311
bool rsrvd_sym_usr_disabled() const
Definition: exprtk.hpp:19436
parser_t * parser_
Definition: exprtk.hpp:34368
T equal_impl(const T v0, const T v1, int_type_tag)
Definition: exprtk.hpp:886
char_cptr base() const
Definition: exprtk.hpp:8038
double time() const
Definition: exprtk.hpp:36413
const range_t & range_ref() const
Definition: exprtk.hpp:8053
const std::size_t stride_
Definition: exprtk.hpp:3152
ptr_t * p_
Definition: exprtk.hpp:20740
opr_base< T >::Type Type
Definition: exprtk.hpp:12365
expression_node_ptr parse_define_vector_statement(const std::string &vec_name)
Definition: exprtk.hpp:23752
std::pair< lexer::token::token_type, lexer::token::token_type > token_pair_t
Definition: exprtk.hpp:3624
axpbz< T > b1_axpbz
Definition: exprtk.hpp:38185
bool const_range()
Definition: exprtk.hpp:6876
operator_type operation_
Definition: exprtk.hpp:5830
Definition: exprtk.hpp:5243
scoped_bool_negator(bool &bb)
Definition: exprtk.hpp:20815
results_context_t * results_context_
Definition: exprtk.hpp:34661
igfun_t::parameter_list_t parameter_list_t
Definition: exprtk.hpp:37833
bool numeric_check_enabled() const
Definition: exprtk.hpp:19428
operator_type operation() const
Definition: exprtk.hpp:14800
Definition: exprtk.hpp:37733
static std::string id(expression_generator< Type > &expr_gen, const details::operator_type o0, const details::operator_type o1, const details::operator_type o2)
Definition: exprtk.hpp:30572
details::T0oT1oT2_sf3< T, T0, T1, T2 > sf3_type
Definition: exprtk.hpp:14331
range_data_type< T > range_data_type_t
Definition: exprtk.hpp:11420
Definition: exprtk.hpp:8851
vector_interface< T > * ivector_ptr
Definition: exprtk.hpp:13035
function_compositor()
Definition: exprtk.hpp:35898
static expression_node_ptr process(expression_generator< Type > &, const details::operator_type &, expression_node_ptr(&)[2])
Definition: exprtk.hpp:33568
Definition: exprtk.hpp:4437
generic_type::vector_view vector_t
Definition: exprtk.hpp:37642
T process(const operator_type operation, const T arg)
Definition: exprtk.hpp:4880
Definition: exprtk.hpp:4442
Definition: exprtk.hpp:4925
static std::string id(expression_generator< Type > &expr_gen, const details::operator_type o0, const details::operator_type o1, const details::operator_type o2)
Definition: exprtk.hpp:31252
T value() const
Definition: exprtk.hpp:9995
expression_node< T >::node_type type() const
Definition: exprtk.hpp:15254
settings_store settings_t
Definition: exprtk.hpp:19813
static T process(const std::string &t1, const std::string &t2)
Definition: exprtk.hpp:12054
function & name(const std::string &n)
Definition: exprtk.hpp:35468
expression_node_ptr synthesize_expression(F *f, expression_node_ptr(&branch)[N])
Definition: exprtk.hpp:34322
bool is_string_function_node(const expression_node< T > *node)
Definition: exprtk.hpp:15352
Definition: exprtk.hpp:9230
std::vector< expression_node_ptr > arg_list_t
Definition: exprtk.hpp:26603
value_ptr value_at(const std::size_t &index) const
Definition: exprtk.hpp:5296
igfun_t::generic_type generic_type
Definition: exprtk.hpp:37834
Definition: exprtk.hpp:4426
vocovov_t::sf4_type sf4_type
Definition: exprtk.hpp:32780
expression_node< T >::node_type type() const
Definition: exprtk.hpp:11718
void clear()
Definition: exprtk.hpp:2039
data_t data
Definition: exprtk.hpp:4615
T0oT1(T0oT1< T, T0, T1 > &)
Definition: exprtk.hpp:13748
Definition: exprtk.hpp:4451
T floor_impl(const T v, real_type_tag)
Definition: exprtk.hpp:1293
expression_node< T >::node_type type() const
Definition: exprtk.hpp:14795
static T process_5(const Sequence &arg_list)
Definition: exprtk.hpp:12480
static expression_node_ptr process(expression_generator< Type > &expr_gen, const details::operator_type &operation, expression_node_ptr(&branch)[2])
Definition: exprtk.hpp:31924
Definition: exprtk.hpp:4004
expression_node< T > * expression_ptr
Definition: exprtk.hpp:15235
std::string * value_
Definition: exprtk.hpp:7560
expression_node< T > * expression_ptr
Definition: exprtk.hpp:9234
Definition: exprtk.hpp:4426
iota< T > ia
Definition: exprtk.hpp:38179
type_store_t & operator[](const std::size_t &index)
Definition: exprtk.hpp:4354
static const std::string assignment_ops_list[]
Definition: exprtk.hpp:483
static T process(Type t1, Type t2, Type t3)
Definition: exprtk.hpp:11997
void stop()
Definition: exprtk.hpp:36391
void scan_string()
Definition: exprtk.hpp:2735
Definition: exprtk.hpp:4421
expression_node_ptr parse_return_statement()
Definition: exprtk.hpp:24663
Definition: exprtk.hpp:2029
vovovov_t::sf4_type sf4_type
Definition: exprtk.hpp:32611
expression_node< T >::node_type type() const
Definition: exprtk.hpp:9468
ipowinv_node< T, PowOp > & operator=(const ipowinv_node< T, PowOp > &)
bool initialised_
Definition: exprtk.hpp:9897
return_envelope_node(expression_ptr body, results_context_t &rc)
Definition: exprtk.hpp:11852
static T process_3(const Sequence &arg_list)
Definition: exprtk.hpp:12273
virtual const std::string & ref() const
Definition: exprtk.hpp:7623
covoc_t::sf3_type sf3_type
Definition: exprtk.hpp:29898
expression_ptr index_
Definition: exprtk.hpp:7181
bool close()
Definition: exprtk.hpp:36674
read()
Definition: exprtk.hpp:36957
vocovoc_t::type1 node_type
Definition: exprtk.hpp:31974
covovoc_t::sf4_type sf4_type
Definition: exprtk.hpp:33005
Definition: exprtk.hpp:4919
struct timeval start_time_
Definition: exprtk.hpp:36434
Definition: exprtk.hpp:4397
T value() const
Definition: exprtk.hpp:13786
void add_auxiliary_symtab(symbol_table_t &symtab)
Definition: exprtk.hpp:35921
expression_node_ptr parse_corpus()
Definition: exprtk.hpp:20292
Definition: exprtk.hpp:4409
static expression_node< T >::node_type type()
Definition: exprtk.hpp:12011
igfun_t::parameter_list_t parameter_list_t
Definition: exprtk.hpp:37738
lexer::helper::numeric_checker numeric_checker_
Definition: exprtk.hpp:34680
token_list_itr_t store_token_itr_
Definition: exprtk.hpp:2839
T1 t1_
Definition: exprtk.hpp:14113
const T & v2_
Definition: exprtk.hpp:9319
expression_node_ptr synthesize_unary_expression(const details::operator_type &operation, expression_node_ptr(&branch)[1])
Definition: exprtk.hpp:26821
exprtk::vector_view< Type > vector_view_t
Definition: exprtk.hpp:5352
expression_node_ptr synthesize_srocs_expression(const details::operator_type &opr, expression_node_ptr(&branch)[2])
Definition: exprtk.hpp:33836
generic_type::scalar_view scalar_t
Definition: exprtk.hpp:37481
T operator()(const std::size_t &ps_index, parameter_list_t parameters)
Definition: exprtk.hpp:37995
details::string_concat_node< T > string_concat_node_t
Definition: exprtk.hpp:18158
vec_data_store< T > vds_t
Definition: exprtk.hpp:10058
vococov_t::type1 node_type
Definition: exprtk.hpp:32086
~str_xrox_node()
Definition: exprtk.hpp:14779
T value() const
Definition: exprtk.hpp:11867
vector_holder_t & vec_holder()
Definition: exprtk.hpp:7113
expression_node< T > * expression_ptr
Definition: exprtk.hpp:5890
T sec_impl(const T v, real_type_tag)
Definition: exprtk.hpp:1305
static T process(const ivector_ptr v)
Definition: exprtk.hpp:13050
T value() const
Definition: exprtk.hpp:6067
functor_t::qfunc_t qfunc_t
Definition: exprtk.hpp:14137
range_interface< T > irange_t
Definition: exprtk.hpp:7998
generic_type::vector_view vector_t
Definition: exprtk.hpp:37434
bool is_sign(const char_t c)
Definition: exprtk.hpp:147
expression_node< typename node_type::value_type > * allocate_rrrr(T1 &t1, T2 &t2, T3 &t3, T4 &t4) const
Definition: exprtk.hpp:15531
Definition: exprtk.hpp:573
expression_node< T > * expression_ptr
Definition: exprtk.hpp:9561
open()
Definition: exprtk.hpp:36824
bool remove_vararg_function(const std::string &vararg_function_name)
Definition: exprtk.hpp:17209
const T & v_
Definition: exprtk.hpp:13312
Definition: exprtk.hpp:4447
Definition: exprtk.hpp:12165
Definition: exprtk.hpp:4923
Definition: exprtk.hpp:37691
#define case_stmt0(op)
bool sf4_optimisable(const std::string &sf4id, quaternary_functor_t &qfunc)
Definition: exprtk.hpp:25659
Definition: exprtk.hpp:4445
Definition: exprtk.hpp:4419
range_t & range_ref()
Definition: exprtk.hpp:8549
expression_node_ptr varnode_optimise_varargfunc(const details::operator_type &operation, Sequence< expression_node_ptr, Allocator > &arg_list)
Definition: exprtk.hpp:27088
opr_base< T >::Type Type
Definition: exprtk.hpp:12149
static void assign(RefType t1, Type t2)
Definition: exprtk.hpp:11998
irange_t * irange_ptr
Definition: exprtk.hpp:7732
bool is_string_condition_node(const expression_node< T > *node)
Definition: exprtk.hpp:15358
const T c_
Definition: exprtk.hpp:14709
Definition: exprtk.hpp:7482
Definition: exprtk.hpp:2028
T value() const
Definition: exprtk.hpp:11069
close()
Definition: exprtk.hpp:36869
vococov_t::type3 node_type
Definition: exprtk.hpp:33061
T d2g_impl(const T v, real_type_tag)
Definition: exprtk.hpp:1309
T0oT1oT2oT3_sf4ext(node_type &)
Definition: exprtk.hpp:14293
void reset()
Definition: exprtk.hpp:18965
const bfunc_t f1_
Definition: exprtk.hpp:13941
settings_store & disable_all_logic_ops()
Definition: exprtk.hpp:19383
vec_data_store< T > vds_t
Definition: exprtk.hpp:9757
vovovoc_t::type1 node_type
Definition: exprtk.hpp:31692
swap_vecvec_node(expression_ptr branch0, expression_ptr branch1)
Definition: exprtk.hpp:7382
Definition: exprtk.hpp:4411
virtual ~token_scanner()
Definition: exprtk.hpp:2866
vector_node_ptr temp_vec_node_
Definition: exprtk.hpp:10659
igfun_t::parameter_list_t parameter_list_t
Definition: exprtk.hpp:37790
static T result(T v)
Definition: exprtk.hpp:1533
expression_node< typename node_type::value_type > * allocate_cr(const T1 &t1, T2 &t2) const
Definition: exprtk.hpp:15482
ProcessMode process_mode_t
Definition: exprtk.hpp:13765
generator generator_t
Definition: exprtk.hpp:3954
void set_synthesis_error(const std::string &synthesis_error_message)
Definition: exprtk.hpp:34384
Definition: exprtk.hpp:4407
bool is_ivector_node(const expression_node< T > *node)
Definition: exprtk.hpp:5057
std::size_t size() const
Definition: exprtk.hpp:10147
T & v_
Definition: exprtk.hpp:4317
const T & v1_
Definition: exprtk.hpp:9284
Definition: exprtk.hpp:12090
covocov_t::sf4_type sf4_type
Definition: exprtk.hpp:32892
std::size_t line_no
Definition: exprtk.hpp:17991
vocovov_t::sf4_type sf4_type
Definition: exprtk.hpp:31805
generic_type::scalar_view scalar_t
Definition: exprtk.hpp:37740
dependent_entity_collector(const std::size_t options=e_ct_none)
Definition: exprtk.hpp:19073
settings_store(const std::size_t compile_options=compile_all_opts)
Definition: exprtk.hpp:19318
T0oT1(T0 p0, T1 p1, const bfunc_t p2)
Definition: exprtk.hpp:13699
T cosh_impl(const T v, real_type_tag)
Definition: exprtk.hpp:1291
vararg_function_node(VarArgFunction *func, const std::vector< expression_ptr > &arg_list)
Definition: exprtk.hpp:11353
std::map< operator_t, trinary_functor_t > trinary_op_map_t
Definition: exprtk.hpp:18189
void set_max_num_args(FunctionType &func, const std::size_t &num_args)
Definition: exprtk.hpp:15832
Definition: exprtk.hpp:4394
Definition: exprtk.hpp:12932
static expression_node_ptr process(expression_generator< Type > &expr_gen, const details::operator_type &operation, expression_node_ptr(&branch)[2])
Definition: exprtk.hpp:28278
virtual const T & v1() const =0
expression_node< T >::node_type type() const
Definition: exprtk.hpp:9372
const range_t & range_ref() const
Definition: exprtk.hpp:7701
bool initialised_
Definition: exprtk.hpp:8566
static const double pi
Definition: exprtk.hpp:739
covoc_t::sf3_type sf3_type
Definition: exprtk.hpp:30012
expression_ptr test_
Definition: exprtk.hpp:8846
static std::string id(expression_generator< Type > &expr_gen, const details::operator_type o0, const details::operator_type o1, const details::operator_type o2)
Definition: exprtk.hpp:33162
Definition: exprtk.hpp:4452
static std::string id(expression_generator< Type > &expr_gen, const details::operator_type o0, const details::operator_type o1, const details::operator_type o2)
Definition: exprtk.hpp:30488
stringvar_node_t * stringvar_node_ptr
Definition: exprtk.hpp:18241
operator_type operation() const
Definition: exprtk.hpp:14155
T * data_ptr_t
Definition: exprtk.hpp:4068
Definition: exprtk.hpp:4419
Definition: exprtk.hpp:4429
token_type
Definition: exprtk.hpp:2015
func_1param()
Definition: exprtk.hpp:35741
T2 t2() const
Definition: exprtk.hpp:14263
Definition: exprtk.hpp:4915
vovov_t::sf3_type sf3_type
Definition: exprtk.hpp:29417
std::string get_vector_name(const vector_holder_ptr &ptr) const
Definition: exprtk.hpp:18924
expression_node< typename node_type::value_type > * allocate(const T1 &t1, const T2 &t2) const
Definition: exprtk.hpp:15475
expression_ptr alternative_
Definition: exprtk.hpp:8730
void skip_comments()
Definition: exprtk.hpp:2363
range_pack()
Definition: exprtk.hpp:6830
bool is_binary_node(const expression_node< T > *node)
Definition: exprtk.hpp:5009
std::size_t size
Definition: exprtk.hpp:4614
expression_node< typename node_type::value_type > * allocate() const
Definition: exprtk.hpp:15447
expression_node_ptr for_loop(expression_node_ptr &initialiser, expression_node_ptr &condition, expression_node_ptr &incrementor, expression_node_ptr &loop_body, bool brkcont=false) const
Definition: exprtk.hpp:26475
ff08_functor f
Definition: exprtk.hpp:16112
static T process_3(const Sequence &arg_list)
Definition: exprtk.hpp:12466
std::string type_id() const
Definition: exprtk.hpp:13998
T3 t3_
Definition: exprtk.hpp:14299
void load_from(const symbol_table< T > &st)
Definition: exprtk.hpp:17419
bool invalid() const
Definition: exprtk.hpp:23216
expression_node< T > * expression_ptr
Definition: exprtk.hpp:7316
Definition: exprtk.hpp:36596
T min_impl(const T v0, const T v1, real_type_tag)
Definition: exprtk.hpp:861
expression_node_ptr parse_symtab_symbol()
Definition: exprtk.hpp:24861
std::string diagnostic
Definition: exprtk.hpp:17988
T operator()(const std::size_t &ps_index, parameter_list_t parameters)
Definition: exprtk.hpp:37495
const bool loop_body_deletable_
Definition: exprtk.hpp:6352
expression_node< T >::node_type type() const
Definition: exprtk.hpp:14733
Type * ptr_t
Definition: exprtk.hpp:20713
Definition: exprtk.hpp:14492
settings_compilation_options
Definition: exprtk.hpp:19231
Definition: exprtk.hpp:10995
void process_lexer_errors()
Definition: exprtk.hpp:20023
expression_node< typename node_type::value_type > * allocate_rrrrr(T1 &t1, T2 &t2, T3 &t3, T4 &t4, T5 &t5) const
Definition: exprtk.hpp:15538
opr_base< T >::Type Type
Definition: exprtk.hpp:12062
vector_node_ptr vec() const
Definition: exprtk.hpp:10281
std::string function_name_
Definition: exprtk.hpp:23318
Definition: exprtk.hpp:15164
T nor_impl(const T v0, const T v1, real_type_tag)
Definition: exprtk.hpp:1136
Definition: exprtk.hpp:4411
control_block(const std::size_t &dsize, data_t dptr, bool dstrct=false)
Definition: exprtk.hpp:4567
ipow_node(const T &v)
Definition: exprtk.hpp:15141
static T process(const T &, const T &)
Definition: exprtk.hpp:12187
parser_t & parser_
Definition: exprtk.hpp:18502
expression_ptr condition_
Definition: exprtk.hpp:6576
covovoc_t::type3 node_type
Definition: exprtk.hpp:33004
T asin_impl(const T v, real_type_tag)
Definition: exprtk.hpp:1285
expression_node_ptr parse_multi_sequence(const std::string &source="")
Definition: exprtk.hpp:22520
Definition: exprtk.hpp:18111
void release()
Definition: exprtk.hpp:5692
T0 t0() const
Definition: exprtk.hpp:14165
~string_size_node()
Definition: exprtk.hpp:8279
T0oT1oT2_sf3ext(T0 p0, T1 p1, T2 p2)
Definition: exprtk.hpp:14052
details::T0oT1oT2_define< T, const_t, cref_t, cref_t > covov_t
Definition: exprtk.hpp:18205
bool is_generally_string_node(const expression_node< T > *node)
Definition: exprtk.hpp:15382
control_block(st_data *data)
Definition: exprtk.hpp:16661
std::pair< bool, type_ptr > type_pair_t
Definition: exprtk.hpp:16211
Definition: exprtk.hpp:5545
Definition: exprtk.hpp:2024
covovov_t::type4 node_type
Definition: exprtk.hpp:33341
T modulus_impl(const T v0, const T v1, int_type_tag)
Definition: exprtk.hpp:935
Definition: exprtk.hpp:10819
static std::string result()
Definition: exprtk.hpp:13455
opr_base< T >::Type Type
Definition: exprtk.hpp:12112
results_context< T > results_context_t
Definition: exprtk.hpp:11850
Definition: exprtk.hpp:18957
void clear_variables(const bool delete_node=true)
Definition: exprtk.hpp:16740
generic_type::scalar_view scalar_t
Definition: exprtk.hpp:38031
expression_node_ptr parse_break_statement()
Definition: exprtk.hpp:23663
std::size_t size() const
Definition: exprtk.hpp:10640
Definition: exprtk.hpp:4402
lexer::helper::operator_joiner operator_joiner_3_
Definition: exprtk.hpp:34677
static T process(const Sequence< Type, Allocator > &arg_list)
Definition: exprtk.hpp:12648
sos_node(SType0 p0, SType1 p1)
Definition: exprtk.hpp:14723
bool inequality_enabled(const details::operator_type &inequality)
Definition: exprtk.hpp:19481
Definition: exprtk.hpp:4406
const value_t & operator[](const std::size_t &i) const
Definition: exprtk.hpp:4245
bool is_control_struct(const std::string &cntrl_strct)
Definition: exprtk.hpp:539
static T evaluate(const Type x, const Type c6, const Type c5, const Type c4, const Type c3, const Type c2, const Type c1, const Type c0)
Definition: exprtk.hpp:35235
Definition: exprtk.hpp:7373
void register_return_results(expression< T > &e)
Definition: exprtk.hpp:34451
expression_node< T > * expression_ptr
Definition: exprtk.hpp:6361
details::assignment_vec_node< T > assignment_vec_node_t
Definition: exprtk.hpp:18168
std::string & s1()
Definition: exprtk.hpp:14948
irange_t * irange_ptr
Definition: exprtk.hpp:7860
operator_type operation() const
Definition: exprtk.hpp:14567
Definition: exprtk.hpp:2020
Definition: exprtk.hpp:4907
uvouv_node< T > & operator=(uvouv_node< T > &)
Definition: exprtk.hpp:4422
expression_node< T > * expression_ptr
Definition: exprtk.hpp:7005
const std::size_t size_
Definition: exprtk.hpp:4122
bool strength_reduction_enabled() const
Definition: exprtk.hpp:25559
Type * ptr_t
Definition: exprtk.hpp:20783
generic_function_ptr get_string_function(const std::string &function_name) const
Definition: exprtk.hpp:18724
expression_node_ptr synthesize_socsr_expression(const details::operator_type &opr, expression_node_ptr(&branch)[2])
Definition: exprtk.hpp:33773
T operator()(const std::size_t &ps_index, parameter_list_t parameters)
Definition: exprtk.hpp:38093
range_interface< T > irange_t
Definition: exprtk.hpp:8861
lexer::helper::helper_assembly helper_assembly_
Definition: exprtk.hpp:34673
void reset()
Definition: exprtk.hpp:20397
irange_t * irange_ptr
Definition: exprtk.hpp:14976
Definition: exprtk.hpp:13757
type & operator=(const type &vds)
Definition: exprtk.hpp:4657
opr_base< T >::Type Type
Definition: exprtk.hpp:12723
token token_t
Definition: exprtk.hpp:2189
~generic_string_range_node()
Definition: exprtk.hpp:7763
Definition: exprtk.hpp:2017
results_context_t & results_ctx()
Definition: exprtk.hpp:34624
branch_t branch_[4]
Definition: exprtk.hpp:5976
settings_store & enable_local_vardef()
Definition: exprtk.hpp:19359
std::size_t parameter_count_
Definition: exprtk.hpp:11307
static details::operator_type operation()
Definition: exprtk.hpp:12125
Definition: exprtk.hpp:4423
virtual ~cob_base_node()
Definition: exprtk.hpp:13174
bov_node< T, Operation > & operator=(const bov_node< T, Operation > &)
expression_node< T >::node_type type() const
Definition: exprtk.hpp:6752
vararg_function_ptr get_vararg_function(const std::string &vararg_function_name) const
Definition: exprtk.hpp:16852
Definition: exprtk.hpp:4442
Definition: exprtk.hpp:4439
variable_node(T &v)
Definition: exprtk.hpp:6787
static expression_node_ptr process(expression_generator< Type > &expr_gen, const details::operator_type &operation, expression_node_ptr(&branch)[2])
Definition: exprtk.hpp:32786
bool valid_operator(const details::operator_type &operation, unary_functor_t &uop)
Definition: exprtk.hpp:25576
const bool loop_body_deletable_
Definition: exprtk.hpp:6414
~vector_elem_node()
Definition: exprtk.hpp:7085
symbol_table_t symbol_table_
Definition: exprtk.hpp:36126
vector_view(const vector_view< T > &vv)
Definition: exprtk.hpp:4076
stringvar_ptr get_stringvar(const std::string &string_name) const
Definition: exprtk.hpp:16831
~str_xoxr_node()
Definition: exprtk.hpp:14842
vector_node< T > * vector_node_ptr
Definition: exprtk.hpp:9756
opr_base< T >::Type Type
Definition: exprtk.hpp:12176
T operator()(const std::size_t &ps_index, parameter_list_t parameters)
Definition: exprtk.hpp:37213
Definition: exprtk.hpp:4423
static expression_node_ptr process(expression_generator< Type > &expr_gen, const details::operator_type &operation, expression_node_ptr(&branch)[2])
Definition: exprtk.hpp:31270
expression_ptr body_
Definition: exprtk.hpp:11897
Definition: exprtk.hpp:35807
node_type & operator=(node_type &)
Definition: exprtk.hpp:13837
bipow_node(expression_ptr brnch)
Definition: exprtk.hpp:15172
T value() const
Definition: exprtk.hpp:14410
T3 t3() const
Definition: exprtk.hpp:14268
vds_t vds_
Definition: exprtk.hpp:10967
expression_node< T >::node_type type() const
Definition: exprtk.hpp:6255
T acos_impl(const T v, real_type_tag)
Definition: exprtk.hpp:1283
std::string & s0()
Definition: exprtk.hpp:14805
expression_node< T > * expression_ptr
Definition: exprtk.hpp:10018
expression_node< T > * expression_ptr
Definition: exprtk.hpp:5784
bool is_vector_node(const expression_node< T > *node)
Definition: exprtk.hpp:5051
static expression_node< T >::node_type type()
Definition: exprtk.hpp:12179
static T result(T v)
Definition: exprtk.hpp:1563
T value() const
Definition: exprtk.hpp:7324
std::vector< token_t >::iterator token_list_itr_t
Definition: exprtk.hpp:2191
Definition: exprtk.hpp:2185
string_base_node< T > * str_base_ptr
Definition: exprtk.hpp:8333
string_base_node< T > * str_base_ptr
Definition: exprtk.hpp:14972
range_ptr str1_range_ptr_
Definition: exprtk.hpp:8220
parser_t parser_
Definition: exprtk.hpp:36127
bool add_infinity()
Definition: exprtk.hpp:17245
uchar_t buffer[64]
Definition: exprtk.hpp:5436
expression_node_ptr synthesize_swap_expression(expression_node_ptr(&branch)[2])
Definition: exprtk.hpp:27895
generic_type::vector_view vector_t
Definition: exprtk.hpp:37585
Operation operation_t
Definition: exprtk.hpp:14498
std::string expression_
Definition: exprtk.hpp:35487
x y t t *t x y t t t x y t t t x *y t *t t x *y t *t t x y t t t x y t t t t(t+t)") define_sfop3(16
bool is_sf4ext_node(const expression_node< T > *n)
Definition: exprtk.hpp:14303
vector_node_ptr vec() const
Definition: exprtk.hpp:10932
bool is_genricstring_range_node(const expression_node< T > *node)
Definition: exprtk.hpp:15376
all_false< T > af
Definition: exprtk.hpp:38168
vec_data_store< T > vds_t
Definition: exprtk.hpp:7380
swap_genstrings_node(expression_ptr branch0, expression_ptr branch1)
Definition: exprtk.hpp:8082
~while_loop_bc_node()
Definition: exprtk.hpp:6370
expression_node< typename node_type::value_type > * allocate_tttt(T1 t1, T2 t2, T3 t3, T4 t4) const
Definition: exprtk.hpp:15517
static details::operator_type operation()
Definition: exprtk.hpp:12106
std::size_t process_stride_3(generator &g)
Definition: exprtk.hpp:3126
Definition: exprtk.hpp:18109
igfun_t::generic_type generic_type
Definition: exprtk.hpp:37153
Definition: exprtk.hpp:4404
Definition: exprtk.hpp:4434
Definition: exprtk.hpp:1531
settings_store & disable_all_inequality_ops()
Definition: exprtk.hpp:19410
bool function_disabled(const std::string &function_name)
Definition: exprtk.hpp:19490
static T process_7(const Sequence &arg_list)
Definition: exprtk.hpp:12805
void assign(const parameter_list_t &pl)
Definition: exprtk.hpp:4374
type_store & front()
Definition: exprtk.hpp:4192
char char_t
Definition: exprtk.hpp:87
details::assignment_node< T > assignment_node_t
Definition: exprtk.hpp:18164
ff12_functor f
Definition: exprtk.hpp:16157
vector_node< T > * vector_node_ptr
Definition: exprtk.hpp:10825
bool enable_collect_vars_
Definition: exprtk.hpp:19796
Definition: exprtk.hpp:36556
static T result(T v)
Definition: exprtk.hpp:1555
static std::string id(expression_generator< Type > &expr_gen, const details::operator_type o0, const details::operator_type o1, const details::operator_type o2)
Definition: exprtk.hpp:31793
SType0 s0_
Definition: exprtk.hpp:14817
symtab_store symtab_store_
Definition: exprtk.hpp:34655
char_cptr base() const
Definition: exprtk.hpp:8539
Definition: exprtk.hpp:4409
std::pair< expression_ptr, bool > branch_t
Definition: exprtk.hpp:11025
bool add(const std::string &symbol_name, exprtk::vector_view< T > &v, const bool is_const=false)
Definition: exprtk.hpp:16350
Definition: exprtk.hpp:11779
std::size_t size() const
Definition: exprtk.hpp:2237
Definition: exprtk.hpp:4445
static details::operator_type operation()
Definition: exprtk.hpp:12000
Definition: exprtk.hpp:4920
static bool is_unary(const expression< T > &expr)
Definition: exprtk.hpp:17938
static std::string id(expression_generator< Type > &expr_gen, const details::operator_type o0, const details::operator_type o1)
Definition: exprtk.hpp:29588
void scan_token()
Definition: exprtk.hpp:2440
std::vector< expression_ptr > arg_list_
Definition: exprtk.hpp:11404
static T process(const arg_list_t &arg)
Definition: exprtk.hpp:26664
std::pair< expression_ptr, bool > branch_t
Definition: exprtk.hpp:11422
Operation operation_t
Definition: exprtk.hpp:14402
bool is_rebasevector_celem_node(const expression_node< T > *node)
Definition: exprtk.hpp:5045
details::vector_elem_node< T > vector_elem_node_t
Definition: exprtk.hpp:18147
ff11_functor f
Definition: exprtk.hpp:16145
opr_base< T >::RefType RefType
Definition: exprtk.hpp:12042
expression_node< T >::node_type type() const
Definition: exprtk.hpp:6653
Definition: exprtk.hpp:4406
T sinc_impl(T v, real_type_tag)
Definition: exprtk.hpp:1269
const range_t & range_ref() const
Definition: exprtk.hpp:8708
Definition: exprtk.hpp:18112
void register_local_vars(expression< T > &e)
Definition: exprtk.hpp:34392
Definition: exprtk.hpp:13094
details::T0oT1oT2oT3_define< T, cref_t, cref_t, cref_t, const_t > vovovoc_t
Definition: exprtk.hpp:18211
expression_node_t * expression_node_ptr
Definition: exprtk.hpp:18173
bool all_nodes_variables(Sequence< expression_node< T > *, Allocator > &b)
Definition: exprtk.hpp:5183
~cons_conditional_node()
Definition: exprtk.hpp:6054
Definition: exprtk.hpp:13190
bool cocob_optimisable(const details::operator_type &operation, expression_node_ptr(&branch)[2]) const
Definition: exprtk.hpp:25904
vector_view_impl operator=(const vector_view_impl &)
freefunc01(ff01_functor ff)
Definition: exprtk.hpp:16037
bool run_modifiers(lexer::generator &g)
Definition: exprtk.hpp:3849
bool add(const function &f, const bool override=false)
Definition: exprtk.hpp:35946
void pre()
Definition: exprtk.hpp:35593
Definition: exprtk.hpp:4422
string_concat_node(const operator_type &opr, expression_ptr branch0, expression_ptr branch1)
Definition: exprtk.hpp:7862
Definition: exprtk.hpp:4913
expression_node< T >::node_type type() const
Definition: exprtk.hpp:7706
Definition: exprtk.hpp:3405
range_t & range_ref()
Definition: exprtk.hpp:7628
igeneric_function(const std::string &param_seq="", const return_type rtr_type=e_rtrn_scalar)
Definition: exprtk.hpp:15962
Definition: exprtk.hpp:38118
T0 t0_
Definition: exprtk.hpp:14296
unknown_symbol_resolver(const usr_mode m=e_usrmode_default)
Definition: exprtk.hpp:19015
Definition: exprtk.hpp:4452
bool enable_replacer_
Definition: exprtk.hpp:19789
bool add_vector(const std::string &vector_name, exprtk::vector_view< T > &v)
Definition: exprtk.hpp:17169
std::string value_
Definition: exprtk.hpp:8726
expression_node< T >::node_type type() const
Definition: exprtk.hpp:6202
Definition: exprtk.hpp:10325
expression_node< T >::node_type type() const
Definition: exprtk.hpp:9273
T and_impl(const T v0, const T v1, real_type_tag)
Definition: exprtk.hpp:1100
Definition: exprtk.hpp:2020
T derivative(const expression< T > &e, T &x, const T &h=T(0.00000001))
Definition: exprtk.hpp:34886
virtual T const T &virtual empty_method_body T const T const T const T &virtual empty_method_body T const T const T const T const T const T &virtual empty_method_body T const T const T const T const T const T const T const T &virtual empty_method_body T const T const T const T const T const T const T const T const T const T &virtual empty_method_body T const T const T const T const T const T const T const T const T const T const T const T &virtual empty_method_body T const T const T const T const T const T const T const T const T const T const T const T const T const T &virtual empty_method_body T const T const T const T const T const T const T const T const T const T const T const T const T const T const T const T &virtual empty_method_body T const T const T const T const T const T const T const T const T const T const T const T const T const T const T const T const T const T &virtual empty_method_body T const T const T const T const T const T const T const T const T const T const T const T const T const T const T const T const T const T const T const T &empty_method_body std::size_t param_count
Definition: exprtk.hpp:15923
opr_base< T >::RefType RefType
Definition: exprtk.hpp:12007
param_seq_list_t param_seq_list_
Definition: exprtk.hpp:23319
T value() const
Definition: exprtk.hpp:6148
range_t base_range_
Definition: exprtk.hpp:7843
bool is_constpow_operation(const details::operator_type &operation, expression_node_ptr(&branch)[2])
Definition: exprtk.hpp:25994
std::size_t size() const
Definition: exprtk.hpp:9878
functor_t::qfunc_t quaternary_functor_t
Definition: exprtk.hpp:9003
expression< T > & release()
Definition: exprtk.hpp:17745
symbol_table(const symbol_table< T > &st)
Definition: exprtk.hpp:16716
branch_t branch_[1]
Definition: exprtk.hpp:14649
lexer::token_scanner * error_token_scanner
Definition: exprtk.hpp:3942
T operator()(const std::size_t &ps_index, parameter_list_t parameters)
Definition: exprtk.hpp:37897
range_pack< T > range_t
Definition: exprtk.hpp:5552
Definition: exprtk.hpp:2021
~scoped_deq_delete()
Definition: exprtk.hpp:20758
Definition: exprtk.hpp:4394
T cot_impl(const T v, real_type_tag)
Definition: exprtk.hpp:1304
std::size_t vector_size() const
Definition: exprtk.hpp:5304
static std::string id(expression_generator< Type > &expr_gen, const details::operator_type o0, const details::operator_type o1, const details::operator_type o2)
Definition: exprtk.hpp:31906
vector_node_ptr vec0_node_ptr_
Definition: exprtk.hpp:10500
Definition: exprtk.hpp:4410
Definition: exprtk.hpp:18105
static std::string id(expression_generator< Type > &expr_gen, const details::operator_type o0, const details::operator_type o1)
Definition: exprtk.hpp:29648
Definition: exprtk.hpp:16073
virtual ~sf3ext_type_node()
Definition: exprtk.hpp:14032
T0oT1oT2oT3(node_type &)
Definition: exprtk.hpp:13933
str_base_ptr str0_base_ptr_
Definition: exprtk.hpp:8567
static T process(const Sequence< Type, Allocator > &arg_list)
Definition: exprtk.hpp:12426
std::string str() const
Definition: exprtk.hpp:8534
void cleanup()
Definition: exprtk.hpp:18457
static expression_node< T > * allocate(Allocator &allocator, T0 p0, T1 p1, T2 p2, tfunc_t p3)
Definition: exprtk.hpp:14009
bool & collect_functions()
Definition: exprtk.hpp:19142
swap_generic_node(expression_ptr var0, expression_ptr var1)
Definition: exprtk.hpp:7349
const T & v_
Definition: exprtk.hpp:14537
token & set_string(const Iterator begin, const Iterator end, const Iterator base_begin=Iterator(0))
Definition: exprtk.hpp:2079
void update(const T &v0, const T &v1)
Definition: exprtk.hpp:35520
static std::string id(expression_generator< Type > &expr_gen, const details::operator_type o0, const details::operator_type o1, const details::operator_type o2)
Definition: exprtk.hpp:31013
Definition: exprtk.hpp:10664
binary_ext_node(expression_ptr branch0, expression_ptr branch1)
Definition: exprtk.hpp:5842
bool compile_expression(const std::string &name, const std::string &expression, const Sequence< std::string, Allocator > &input_var_list, bool return_present=false)
Definition: exprtk.hpp:35955
virtual bool operator()(const token &)
Definition: exprtk.hpp:2944
covovoc_t::type1 node_type
Definition: exprtk.hpp:32030
static const double _2_pi
Definition: exprtk.hpp:744
expression_node_ptr get_variable(const T &v)
Definition: exprtk.hpp:18474
static std::string id()
Definition: exprtk.hpp:13540
bool add(const std::string &symbol_name, RawType &t, const bool is_const=false)
Definition: exprtk.hpp:16363
T round_impl(const T v, real_type_tag)
Definition: exprtk.hpp:1012
Definition: exprtk.hpp:8225
vovocov_t::sf4_type sf4_type
Definition: exprtk.hpp:32724
static T process_3(const Sequence &arg_list)
Definition: exprtk.hpp:12607
control_block * control_block_
Definition: exprtk.hpp:17915
covovoc_t::sf4_type sf4_type
Definition: exprtk.hpp:32537
static expression_node_ptr process(expression_generator< Type > &expr_gen, const details::operator_type &operation, expression_node_ptr(&branch)[2])
Definition: exprtk.hpp:33180
static std::string result()
Definition: exprtk.hpp:13452
generic_type::parameter_list parameter_list_t
Definition: exprtk.hpp:11791
std::pair< expression_ptr, bool > branch_t
Definition: exprtk.hpp:14597
~for_loop_bc_node()
Definition: exprtk.hpp:6500
static bool cmp(const char_t c0, const char_t c1)
Definition: exprtk.hpp:567
static std::string id()
Definition: exprtk.hpp:14094
Definition: exprtk.hpp:2030
ror()
Definition: exprtk.hpp:37486
void set_ref(value_ptr *ref)
Definition: exprtk.hpp:5358
static T result(T v)
Definition: exprtk.hpp:1559
#define poly_rtrn(NN)
Definition: exprtk.hpp:35309
static T process(const T &t0, const T &t1, const T &t2, const T &t3, const bfunc_t bf0, const bfunc_t bf1, const bfunc_t bf2)
Definition: exprtk.hpp:13552
Definition: exprtk.hpp:18998
#define register_sf4ext(Op)
bool control_struct_disabled(const std::string &control_struct)
Definition: exprtk.hpp:19498
bool collect_functions_
Definition: exprtk.hpp:19211
details::T0oT1oT2_define< T, cref_t, cref_t, const_t > vovoc_t
Definition: exprtk.hpp:18203
#define exprtk_register_int_type_tag(T)
Definition: exprtk.hpp:772
token & set_numeric(const Iterator begin, const Iterator end, const Iterator base_begin=Iterator(0))
Definition: exprtk.hpp:2069
Definition: exprtk.hpp:4420
ff06_functor f
Definition: exprtk.hpp:16090
Definition: exprtk.hpp:4433
igfun_t::parameter_list_t parameter_list_t
Definition: exprtk.hpp:37105
~bipow_node()
Definition: exprtk.hpp:15177
const bool single_value_initialse_
Definition: exprtk.hpp:7308
igfun_t::parameter_list_t parameter_list_t
Definition: exprtk.hpp:37198
#define case_stmt(N)
Definition: exprtk.hpp:26605
expression_node< typename node_type::value_type > * allocate(const T1 &t1, const T2 &t2, const T3 &t3) const
Definition: exprtk.hpp:15545
Definition: exprtk.hpp:381
bool in_use() const
Definition: exprtk.hpp:36420
vovovov_t::sf4_type sf4_type
Definition: exprtk.hpp:31641
static T_ execute(ifunction &f, T_(&v)[11])
Definition: exprtk.hpp:11225
string_base_node< T > * str_base_ptr
Definition: exprtk.hpp:7728
Definition: exprtk.hpp:9481
std::vector< type_store_t > typestore_list_t
Definition: exprtk.hpp:11425
std::string & ref()
Definition: exprtk.hpp:7533
Definition: exprtk.hpp:4491
Definition: exprtk.hpp:4456
static T evaluate(const Type x, const Type c2, const Type c1, const Type c0)
Definition: exprtk.hpp:35279
static expression_node_ptr process(expression_generator< Type > &expr_gen, const details::operator_type &operation, expression_node_ptr(&branch)[2])
Definition: exprtk.hpp:31699
std::size_t min_num_args_
Definition: exprtk.hpp:15789
Definition: exprtk.hpp:2025
Definition: exprtk.hpp:4430
Definition: exprtk.hpp:4410
token_scanner(const std::size_t &stride)
Definition: exprtk.hpp:2869
static std::pair< bool, vector_t * > make(exprtk::vector_view< T > &v, const bool is_const=false)
Definition: exprtk.hpp:16315
expression_node< T > * expression_ptr
Definition: exprtk.hpp:10514
branch_t branch_[3]
Definition: exprtk.hpp:5937
functor_t::qfunc_t quaternary_functor_t
Definition: exprtk.hpp:18180
details::operator_type operation
Definition: exprtk.hpp:20406
bool rebaseable() const
Definition: exprtk.hpp:5428
bool is_conststr_stringvar(const std::string &symbol_name) const
Definition: exprtk.hpp:17351
Definition: exprtk.hpp:2027
Definition: exprtk.hpp:10174
static std::string id(expression_generator< Type > &expr_gen, const details::operator_type o0, const details::operator_type o1)
Definition: exprtk.hpp:29768
RangePack rp0_
Definition: exprtk.hpp:14957
std::string str() const
Definition: exprtk.hpp:8942
range_interface< T > irange_t
Definition: exprtk.hpp:8079
bool is_uv_node(const expression_node< T > *node)
Definition: exprtk.hpp:15310
Definition: exprtk.hpp:7653
token & set_symbol(const Iterator begin, const Iterator end, const Iterator base_begin=Iterator(0))
Definition: exprtk.hpp:2059
T roundn_impl(const T v0, const T, int_type_tag)
Definition: exprtk.hpp:1030
expression_node< T > * branch(const std::size_t &) const
Definition: exprtk.hpp:5528
static details::operator_type operation()
Definition: exprtk.hpp:12180
bool add_element(const scope_element &se)
Definition: exprtk.hpp:18387
T0oT1oT2oT3_sf4< T, T0, T1, T2, T3 > node_type
Definition: exprtk.hpp:14139
Definition: exprtk.hpp:4925
results_context()
Definition: exprtk.hpp:4342
T value_type
Definition: exprtk.hpp:13763
vector_node< T > * vec1_node_ptr_
Definition: exprtk.hpp:10319
exprtk::igeneric_function< T > igfun_t
Definition: exprtk.hpp:37151
static T process_1(const Sequence &arg_list)
Definition: exprtk.hpp:12454
covovov_t::sf4_type sf4_type
Definition: exprtk.hpp:30752
void disable_unknown_symbol_resolver()
Definition: exprtk.hpp:20214
bool sf3_optimisable(const std::string &sf3id, details::operator_type &operation)
Definition: exprtk.hpp:25671
functor_t::bfunc_t binary_functor_t
Definition: exprtk.hpp:18182
expression_node< T >::node_type type() const
Definition: exprtk.hpp:9419
bool commutative_check_enabled() const
Definition: exprtk.hpp:19426
string_literal_node(const std::string &v)
Definition: exprtk.hpp:5589
static T process_4(const Sequence &arg_list)
Definition: exprtk.hpp:12472
Definition: exprtk.hpp:4446
unary_variable_node< T, Operation > & operator=(unary_variable_node< T, Operation > &)
bool create_variable(const std::string &variable_name, const T &value=T(0))
Definition: exprtk.hpp:16942
static std::string id(expression_generator< Type > &expr_gen, const details::operator_type o0, const details::operator_type o1, const details::operator_type o2)
Definition: exprtk.hpp:33330
static T process_4(const Sequence &arg_list)
Definition: exprtk.hpp:12617
str_base_ptr str1_base_ptr_
Definition: exprtk.hpp:8722
static T process(const std::string &t1, const std::string &t2)
Definition: exprtk.hpp:12178
void clear()
Definition: exprtk.hpp:2202
vds_t vds_
Definition: exprtk.hpp:7477
virtual ~uv_base_node()
Definition: exprtk.hpp:13214
bool empty() const
Definition: exprtk.hpp:2232
cov_node(const T &const_var, const T &var)
Definition: exprtk.hpp:14405
func_0param()
Definition: exprtk.hpp:35713
Definition: exprtk.hpp:9750
sequence_vector_impl(sequence_t &seq)
Definition: exprtk.hpp:5325
expression_node_ptr parse_const_string()
Definition: exprtk.hpp:22876
virtual T operator()(const std::vector< T > &)
Definition: exprtk.hpp:15940
dotk< T > dtk
Definition: exprtk.hpp:38187
cached_range_t cache
Definition: exprtk.hpp:6946
Definition: exprtk.hpp:4918
vector_holder(Type *vec, const std::size_t &vec_size)
Definition: exprtk.hpp:5391
static expression_node_ptr process(expression_generator< Type > &expr_gen, const details::operator_type &operation, expression_node_ptr(&branch)[2])
Definition: exprtk.hpp:32317
~vec_data_store()
Definition: exprtk.hpp:4652
static expression_node_ptr process(expression_generator< Type > &expr_gen, const details::operator_type &operation, expression_node_ptr(&branch)[2])
Definition: exprtk.hpp:30389
std::size_t process(generator &g)
Definition: exprtk.hpp:3001
vovovoc_t::type3 node_type
Definition: exprtk.hpp:32666
static std::string id(expression_generator< Type > &expr_gen, const details::operator_type o0, const details::operator_type o1, const details::operator_type o2)
Definition: exprtk.hpp:31963
expression_node< T > * expression_ptr
Definition: exprtk.hpp:14895
bool is_bracket(const char_t c)
Definition: exprtk.hpp:142
std::size_t size() const
Definition: exprtk.hpp:4235
expression_node_ptr parse_continue_statement()
Definition: exprtk.hpp:23728
vec_data_store< T > vds_t
Definition: exprtk.hpp:7196
expression_node< T > * expression_ptr
Definition: exprtk.hpp:11351
data_type type
Definition: exprtk.hpp:17592
std::size_t process(generator &g)
Definition: exprtk.hpp:2878
strvar_node_ptr str0_node_ptr_
Definition: exprtk.hpp:8436
T ncdf_impl(T v, real_type_tag)
Definition: exprtk.hpp:1254
static const std::size_t assignment_ops_list_size
Definition: exprtk.hpp:489
std::size_t max_num_args_
Definition: exprtk.hpp:15790
#define exprtk_debug(params)
Definition: exprtk.hpp:64
std::vector< std::string > param_seq_list_t
Definition: exprtk.hpp:23134
details::char_cptr s_itr_
Definition: exprtk.hpp:2842
vector_elem_node(expression_ptr index, vector_holder_ptr vec_holder)
Definition: exprtk.hpp:7078
expression_node< T > * move_branch(const std::size_t &)
Definition: exprtk.hpp:14637
Definition: exprtk.hpp:4005
Definition: exprtk.hpp:4431
settings_store & disable_all_arithmetic_ops()
Definition: exprtk.hpp:19392
symbol_table_list_t symtab_list_
Definition: exprtk.hpp:18547
Definition: exprtk.hpp:4436
void set_strength_reduction_state(const bool enabled)
Definition: exprtk.hpp:25554
bool invalid_range(const Vector &v, const std::size_t r0, const std::size_t r1)
Definition: exprtk.hpp:37089
void add_symbol(const std::string &symbol, const symbol_type st)
Definition: exprtk.hpp:19171
const std::size_t index_
Definition: exprtk.hpp:7233
exprtk::igeneric_function< T > igfun_t
Definition: exprtk.hpp:37380
bool is_string_vararg_node(const expression_node< T > *node)
Definition: exprtk.hpp:15370
Definition: exprtk.hpp:6480
const bfunc_t f0_
Definition: exprtk.hpp:13940
static expression_node_ptr process(expression_generator< Type > &expr_gen, const details::operator_type &operation, expression_node_ptr(&branch)[2])
Definition: exprtk.hpp:32149
virtual bool populate_value_list() const
Definition: exprtk.hpp:11551
expression_node< T > * expression_ptr
Definition: exprtk.hpp:9328
std::string * value_
Definition: exprtk.hpp:8251
ufunc_t u1()
Definition: exprtk.hpp:13366
void register_return_results(results_context_t *rc)
Definition: exprtk.hpp:17899
static T process(Type t1, Type t2, Type t3)
Definition: exprtk.hpp:12009
const bool loop_body_deletable_
Definition: exprtk.hpp:6582
static std::string id(expression_generator< Type > &, const details::operator_type, const details::operator_type, const details::operator_type)
Definition: exprtk.hpp:32601
~vararg_function_node()
Definition: exprtk.hpp:11361
covovoc_t::sf4_type sf4_type
Definition: exprtk.hpp:32031
static details::operator_type operation()
Definition: exprtk.hpp:12012
vococov_t::sf4_type sf4_type
Definition: exprtk.hpp:31453
range_ptr str0_range_ptr_
Definition: exprtk.hpp:8570
const results_context_t & results() const
Definition: exprtk.hpp:17794
static const std::string inequality_ops_list[]
Definition: exprtk.hpp:491
bool compile(const std::string &expression_string, expression< T > &expr)
Definition: exprtk.hpp:19916
token token_t
Definition: exprtk.hpp:3953
exprtk::igeneric_function< T > igfun_t
Definition: exprtk.hpp:37695
void clear()
Definition: exprtk.hpp:35926
Definition: exprtk.hpp:4394
Definition: exprtk.hpp:5122
Definition: exprtk.hpp:4331
expression_ptr condition_
Definition: exprtk.hpp:6346
bool collect_assignments_enabled() const
Definition: exprtk.hpp:19434
std::string to_str(int i)
Definition: exprtk.hpp:261
T2 t2_
Definition: exprtk.hpp:14023
bool operator()(const lexer::token &t)
Definition: exprtk.hpp:3445
bool match_impl(const Iterator pattern_begin, const Iterator pattern_end, const Iterator data_begin, const Iterator data_end, const typename std::iterator_traits< Iterator >::value_type &zero_or_more, const typename std::iterator_traits< Iterator >::value_type &zero_or_one)
Definition: exprtk.hpp:582
std::size_t options_
Definition: exprtk.hpp:19209
expression_node< T >::node_type type() const
Definition: exprtk.hpp:10478
expression_node< T >::node_type type() const
Definition: exprtk.hpp:11544
node_type & operator=(node_type &)
Definition: exprtk.hpp:14019
inv_binary_op_map_t * inv_binary_op_map_
Definition: exprtk.hpp:34365
Definition: exprtk.hpp:4907
expression_node< T > * expression_ptr
Definition: exprtk.hpp:14496
value_ptr data() const
Definition: exprtk.hpp:5267
void load_sf3_map(sf3_map_t &sf3_map)
Definition: exprtk.hpp:34560
Definition: exprtk.hpp:17974
void clear()
Definition: exprtk.hpp:16767
const T & v() const
Definition: exprtk.hpp:14572
void set_parser(parser_t &p)
Definition: exprtk.hpp:25519
bool & b
Definition: exprtk.hpp:20822
bfunc_t f1() const
Definition: exprtk.hpp:13811
Definition: exprtk.hpp:6776
virtual ~range_interface()
Definition: exprtk.hpp:5554
Definition: exprtk.hpp:16172
bool special_one_parameter_vararg(const details::operator_type &operation)
Definition: exprtk.hpp:27075
Definition: exprtk.hpp:4427
expression_node_ptr synthesize_str_xrox_expression_impl(const details::operator_type &opr, T0 s0, T1 s1, range_t rp0)
Definition: exprtk.hpp:33671
bool symbol_exists(const std::string &symbol_name, const bool check_reserved_symb=true) const
Definition: exprtk.hpp:17309
const vds_t & vds() const
Definition: exprtk.hpp:10650
T value() const
Definition: exprtk.hpp:6383
~scoped_delete()
Definition: exprtk.hpp:20727
std::vector< ifunction< T > * > free_function_list_
Definition: exprtk.hpp:16653
Definition: exprtk.hpp:4408
Definition: exprtk.hpp:2988
const ufunc_t u1_
Definition: exprtk.hpp:13384
T2 t2() const
Definition: exprtk.hpp:13988
function_ptr get_function(const std::string &function_name) const
Definition: exprtk.hpp:16842
static details::operator_type operation()
Definition: exprtk.hpp:12046
static const double _1_pi
Definition: exprtk.hpp:743
static T process_1(const Sequence &arg_list)
Definition: exprtk.hpp:12328
Definition: exprtk.hpp:7188
bool add(const std::string &symbol_name, T *v, const std::size_t v_size, const bool is_const=false)
Definition: exprtk.hpp:16337
expression_node_ptr multi_switch_statement(Sequence< expression_node_ptr, Allocator > &arg_list)
Definition: exprtk.hpp:26732
Definition: exprtk.hpp:14828
bool initialised_
Definition: exprtk.hpp:7838
Definition: exprtk.hpp:4402
vovocov_t::type1 node_type
Definition: exprtk.hpp:31748
~boc_node()
Definition: exprtk.hpp:14668
Definition: exprtk.hpp:5548
ipow_node< T, PowOp > & operator=(const ipow_node< T, PowOp > &)
bool operator()(const std::string &s1, const std::string &s2) const
Definition: exprtk.hpp:199
const vds_t & vds() const
Definition: exprtk.hpp:10493
operator_type type
Definition: exprtk.hpp:4498
const_string_range_node< T > & operator=(const const_string_range_node< T > &)
Definition: exprtk.hpp:37522
results_context< T > results_context_t
Definition: exprtk.hpp:11808
bool is_reserved_symbol(const std::string &symbol) const
Definition: exprtk.hpp:16634
Definition: exprtk.hpp:5980
print< T > p
Definition: exprtk.hpp:36558
vector_holder_ptr temp_
Definition: exprtk.hpp:10502
range_t & range_ref()
Definition: exprtk.hpp:7821
const T & ref() const
Definition: exprtk.hpp:7164
virtual const T & v() const =0
Definition: exprtk.hpp:4151
symbol_table()
Definition: exprtk.hpp:16705
static bool compile(expression_generator< Type > &expr_gen, const std::string &id, T0 t0, T1 t1, T2 t2, expression_node_ptr &result)
Definition: exprtk.hpp:29202
static T null_value
Definition: exprtk.hpp:6781
vococov_t::sf4_type sf4_type
Definition: exprtk.hpp:33062
~scope_handler()
Definition: exprtk.hpp:18526
static expression_node_ptr process(expression_generator< Type > &expr_gen, const details::operator_type &operation, expression_node_ptr(&branch)[2])
Definition: exprtk.hpp:31867
vector_node< T > * vector_node_ptr
Definition: exprtk.hpp:10057
expression_node< T >::node_type type() const
Definition: exprtk.hpp:11648
~parser()
Definition: exprtk.hpp:19850
static std::string id()
Definition: exprtk.hpp:13475
Definition: exprtk.hpp:4407
static expression_node_ptr process(expression_generator< Type > &expr_gen, const details::operator_type &operation, expression_node_ptr(&branch)[2])
Definition: exprtk.hpp:29780
Definition: exprtk.hpp:15076
static T process(Type t1, Type t2)
Definition: exprtk.hpp:12073
Definition: exprtk.hpp:4395
exprtk::igeneric_function< T > igfun_t
Definition: exprtk.hpp:36891
static T process(const std::string &t1, const std::string &t2)
Definition: exprtk.hpp:12064
expression_node< T > * branch(const std::size_t &) const
Definition: exprtk.hpp:5687
static T process(Type t1, Type t2)
Definition: exprtk.hpp:12032
Definition: exprtk.hpp:15406
opr_base< T >::Type Type
Definition: exprtk.hpp:12131
stringvar_node(std::string &v)
Definition: exprtk.hpp:7496
static const std::string reserved_symbols[]
Definition: exprtk.hpp:428
details::variable_node< T > variable_node_t
Definition: exprtk.hpp:18146
typestore_list_t typestore_list_
Definition: exprtk.hpp:11589
expression_node_ptr parse_ternary_conditional_statement(expression_node_ptr condition)
Definition: exprtk.hpp:21453
RangePack rp0_
Definition: exprtk.hpp:14819
static const double pow10[]
Definition: exprtk.hpp:724
Definition: exprtk.hpp:4412
bool register_package(exprtk::symbol_table< T > &symtab)
Definition: exprtk.hpp:36561
Definition: exprtk.hpp:9289
expression()
Definition: exprtk.hpp:17687
range_t & range_ref()
Definition: exprtk.hpp:7543
freefunc03(ff03_functor ff)
Definition: exprtk.hpp:16057
vector_elem_node< T > * vec_node_ptr_
Definition: exprtk.hpp:9973
qfunc_t f() const
Definition: exprtk.hpp:14185
static bool test(const variable_node_t *p, const void *ptr)
Definition: exprtk.hpp:16428
generic_type::vector_view vector_t
Definition: exprtk.hpp:37200
PowOp operation_t
Definition: exprtk.hpp:15170
null_igenfunc< T > igeneric_function_t
Definition: exprtk.hpp:11805
settings_store & enable_assignment_operation(settings_assignment_opr assignment)
Definition: exprtk.hpp:19691
#define define_sfop4(NN, OP0, OP1)
static T evaluate(const Type x, const Type c9, const Type c8, const Type c7, const Type c6, const Type c5, const Type c4, const Type c3, const Type c2, const Type c1, const Type c0)
Definition: exprtk.hpp:35199
Definition: exprtk.hpp:6144
T value() const
Definition: exprtk.hpp:14248
range_t & range_ref()
Definition: exprtk.hpp:11668
Definition: exprtk.hpp:16148
Definition: exprtk.hpp:4422
static expression_node_ptr process(expression_generator< Type > &expr_gen, const details::operator_type &operation, expression_node_ptr(&branch)[2])
Definition: exprtk.hpp:32430
exprtk::igeneric_function< T > igfun_t
Definition: exprtk.hpp:38122
T value() const
Definition: exprtk.hpp:15212
void set_retinvk(bool *retinvk_ptr)
Definition: exprtk.hpp:17907
control_block * control_block_
Definition: exprtk.hpp:4742
Definition: exprtk.hpp:2026
bool register_package(exprtk::symbol_table< T > &symtab)
Definition: exprtk.hpp:37052
static expression_node_ptr process(expression_generator< Type > &expr_gen, const details::operator_type &operation, expression_node_ptr(&branch)[2])
Definition: exprtk.hpp:29900
str_base_ptr str0_base_ptr_
Definition: exprtk.hpp:8217
bool side_effect_present
Definition: exprtk.hpp:18991
expression_node< T >::node_type type() const
Definition: exprtk.hpp:6404
Type value_type
Definition: exprtk.hpp:5247
vararg_function_ptr get_vararg_function(const std::string &vararg_function_name) const
Definition: exprtk.hpp:18682
std::size_t param_seq_index_
Definition: exprtk.hpp:11725
Definition: exprtk.hpp:13466
exprtk::igeneric_function< T > igfun_t
Definition: exprtk.hpp:37832
virtual std::string type_id() const =0
assignment_vec_node(const operator_type &opr, expression_ptr branch0, expression_ptr branch1)
Definition: exprtk.hpp:9642
Definition: exprtk.hpp:4402
vovoc_t::sf3_type sf3_type
Definition: exprtk.hpp:29598
Definition: exprtk.hpp:12039
static expression_node_ptr process(expression_generator< Type > &expr_gen, const details::operator_type &operation, expression_node_ptr(&branch)[2])
Definition: exprtk.hpp:28437
stringvar_node_ptr str_node
Definition: exprtk.hpp:18309
void set_uom(unary_op_map_t &unary_op_map)
Definition: exprtk.hpp:25524
function_N_node(ifunction *func)
Definition: exprtk.hpp:11319
scope_element & get_active_element(const std::string &var_name, const std::size_t index=std::numeric_limits< std::size_t >::max())
Definition: exprtk.hpp:18365
~while_loop_node()
Definition: exprtk.hpp:6177
functor_t::bfunc_t bfunc_t
Definition: exprtk.hpp:13695
virtual ~bov_base_node()
Definition: exprtk.hpp:13163
std::string str() const
Definition: exprtk.hpp:5613
Definition: exprtk.hpp:2019
vec_binop_valvec_node(const operator_type &opr, expression_ptr branch0, expression_ptr branch1)
Definition: exprtk.hpp:10674
node_type & operator=(node_type &)
Definition: exprtk.hpp:13934
static void destroy(control_block *&cntrl_blck)
Definition: exprtk.hpp:4597
bool valid_function_name(const std::string &symbol) const
Definition: exprtk.hpp:18591
void kahan_sum(T &sum, T &error, T v)
Definition: exprtk.hpp:37136
strbase_ptr_t str_node
Definition: exprtk.hpp:6970
T value_type
Definition: exprtk.hpp:14227
const bool condition_deletable_
Definition: exprtk.hpp:6475
lexer::token_modifier * error_token_modifier
Definition: exprtk.hpp:3943
generic_type::scalar_view scalar_t
Definition: exprtk.hpp:37433
freefunc06(ff06_functor ff)
Definition: exprtk.hpp:16087
~unary_branch_node()
Definition: exprtk.hpp:13401
Definition: exprtk.hpp:6357
vector_node< T > * vector_node_ptr
Definition: exprtk.hpp:10515
vec_data_store(const std::size_t &size, data_t data, bool dstrct=false)
Definition: exprtk.hpp:4642
branch_t branch_[1]
Definition: exprtk.hpp:14588
Definition: exprtk.hpp:4404
std::string value_
Definition: exprtk.hpp:7845
bool is_neg_unary_node(const expression_node< T > *node)
Definition: exprtk.hpp:5003
T modulus(const T v0, const T v1)
Definition: exprtk.hpp:1419
expression_node_ptr synthesize_sos_expression_impl(const details::operator_type &opr, T0 s0, T1 s1)
Definition: exprtk.hpp:33725
Definition: exprtk.hpp:20711
settings_store & enable_all_logic_ops()
Definition: exprtk.hpp:19335
Definition: exprtk.hpp:4918
Definition: exprtk.hpp:2851
details::T0oT1oT2oT3< T, T0, T1, T2, T3, typename T0oT1oT20T3process< T >::mode2 > type2
Definition: exprtk.hpp:14340
bool valid() const
Definition: exprtk.hpp:17413
expression_node< T > * expression_ptr
Definition: exprtk.hpp:7074
exprtk_define_erf(float,::erff) exprtk_define_erf(double
void set_allocator(details::node_allocator &na)
Definition: exprtk.hpp:25549
static std::string id(expression_generator< Type > &expr_gen, const details::operator_type o0, const details::operator_type o1, const details::operator_type o2)
Definition: exprtk.hpp:32936
static std::string id(expression_generator< Type > &expr_gen, const details::operator_type o0, const details::operator_type o1, const details::operator_type o2)
Definition: exprtk.hpp:30824
std::size_t size() const
Definition: exprtk.hpp:5413
Definition: exprtk.hpp:4425
Definition: exprtk.hpp:4425
void load_binary_operations_map(binary_op_map_t &m)
Definition: exprtk.hpp:34504
generic_function_t * generic_function_ptr
Definition: exprtk.hpp:16594
const T & v0()
Definition: exprtk.hpp:13351
Definition: exprtk.hpp:17570
stringvar_size_node(std::string &v)
Definition: exprtk.hpp:8235
type_store_t::parameter_list parameter_list_t
Definition: exprtk.hpp:4372
bool delete_ptr
Definition: exprtk.hpp:20804
#define exprtk_error_location
Definition: exprtk.hpp:67
bool is_null_node(const expression_node< T > *node)
Definition: exprtk.hpp:5087
string_range_node(std::string &v, const range_t &rp)
Definition: exprtk.hpp:7578
Definition: exprtk.hpp:4440
Definition: exprtk.hpp:4922
expression_node_ptr synthesize_string_expression(const details::operator_type &opr, expression_node_ptr(&branch)[3])
Definition: exprtk.hpp:34072
Definition: exprtk.hpp:5780
bool delete_ptr
Definition: exprtk.hpp:20771
void copy(const lvr_vec_t &src_v, var_t &dest_v)
Definition: exprtk.hpp:35647
bool * retinvk_ptr()
Definition: exprtk.hpp:11888
T value() const
Definition: exprtk.hpp:5800
bool is_conststr_stringvar(const std::string &symbol_name) const
Definition: exprtk.hpp:18848
functor_t::tfunc_t tfunc_t
Definition: exprtk.hpp:13951
std::set< token_pair_t > set_t
Definition: exprtk.hpp:3625
range_t * range_ptr
Definition: exprtk.hpp:8451
void store()
Definition: exprtk.hpp:2248
vector_holder_ptr temp_
Definition: exprtk.hpp:10813
Definition: exprtk.hpp:4457
Definition: exprtk.hpp:20825
Definition: exprtk.hpp:4428
ufunc_t u0()
Definition: exprtk.hpp:13361
Definition: exprtk.hpp:4919
Definition: exprtk.hpp:8071
static std::string id(expression_generator< Type > &expr_gen, const details::operator_type o0, const details::operator_type o1, const details::operator_type o2)
Definition: exprtk.hpp:32582
Definition: exprtk.hpp:6587
Definition: exprtk.hpp:19252
vovovov_t::type2 node_type
Definition: exprtk.hpp:32142
static details::operator_type operation()
Definition: exprtk.hpp:12086
details::T0oT1oT2oT3_define< T, cref_t, const_t, cref_t, cref_t > vocovov_t
Definition: exprtk.hpp:18213
static const std::string reserved_words[]
Definition: exprtk.hpp:417
static T process_3(const Sequence &arg_list)
Definition: exprtk.hpp:12687
token_t & peek_next_token()
Definition: exprtk.hpp:2268
bool is_const_string_node(const expression_node< T > *node)
Definition: exprtk.hpp:15328
Definition: exprtk.hpp:6665
scope_element_manager(parser< T > &p)
Definition: exprtk.hpp:18321
igfun_t::generic_type generic_type
Definition: exprtk.hpp:37979
range_t range_
Definition: exprtk.hpp:7844
expression_ptr loop_body_
Definition: exprtk.hpp:6474
Definition: exprtk.hpp:2020
varref_t v
Definition: exprtk.hpp:35699
vector_node_t * vector_node_ptr_t
Definition: exprtk.hpp:11418
vector_holder< T > vector_holder_t
Definition: exprtk.hpp:7006
expression_node< T >::node_type type() const
Definition: exprtk.hpp:5603
str_xroxr_node(SType0 p0, SType1 p1, RangePack rp0, RangePack rp1)
Definition: exprtk.hpp:14899
assignment_vec_op_node(const operator_type &opr, expression_ptr branch0, expression_ptr branch1)
Definition: exprtk.hpp:10060
T2_ T2
Definition: exprtk.hpp:13856
vector_node_ptr temp_vec_node_
Definition: exprtk.hpp:10814
std::size_t size() const
Definition: exprtk.hpp:7955
std::vector< unsigned char > delete_branch_
Definition: exprtk.hpp:6661
Definition: exprtk.hpp:4924
T value() const
Definition: exprtk.hpp:9302
bool is_nan(const T v)
Definition: exprtk.hpp:1384
vococov_t::sf4_type sf4_type
Definition: exprtk.hpp:32087
functor_t::tfunc_t trinary_functor_t
Definition: exprtk.hpp:9004
type_store< ivararg_function< T >, ivararg_function< T > > vararg_function_store
Definition: exprtk.hpp:16608
Definition: exprtk.hpp:37785
Definition: exprtk.hpp:4428
Definition: exprtk.hpp:5941
vocovov_t::type2 node_type
Definition: exprtk.hpp:32310
range_t rp_
Definition: exprtk.hpp:7646
bool is_vector(const std::string &vector_name) const
Definition: exprtk.hpp:17383
std::set< std::string, details::ilesscompare > disabled_entity_set_t
Definition: exprtk.hpp:19226
vocov_t::type1 node_type
Definition: exprtk.hpp:29717
details::repeat_until_loop_node< T > repeat_until_loop_node_t
Definition: exprtk.hpp:18138
multimode_strfunction_node(StringFunction *func, const std::size_t &param_seq_index, const std::vector< typename str_function_t::expression_ptr > &arg_list)
Definition: exprtk.hpp:11737
std::vector< lexer::token_scanner * > token_scanner_list
Definition: exprtk.hpp:3937
igfun_t::generic_type generic_type
Definition: exprtk.hpp:38030
expression_node_ptr synthesize_csos_expression(const details::operator_type &opr, expression_node_ptr(&branch)[2])
Definition: exprtk.hpp:33812
virtual expression_node< T > * move_branch(const std::size_t &index)=0
T0oT1oT2oT3_sf4ext(T0 p0, T1 p1, T2 p2, T3 p3)
Definition: exprtk.hpp:14230
static expression_node_ptr process(expression_generator< Type > &expr_gen, const details::operator_type &operation, expression_node_ptr(&branch)[2])
Definition: exprtk.hpp:33517
Definition: exprtk.hpp:13265
static T result(T v)
Definition: exprtk.hpp:1560
details::T0oT1oT2oT3_define< T, cref_t, cref_t, const_t, cref_t > vovocov_t
Definition: exprtk.hpp:18212
static std::string id(expression_generator< Type > &expr_gen, const details::operator_type o0, const details::operator_type o1)
Definition: exprtk.hpp:29828
vararg_function_t * vararg_function_ptr
Definition: exprtk.hpp:16593
const range_t & range_ref() const
Definition: exprtk.hpp:11673
T value() const
Definition: exprtk.hpp:7355
igeneric_function< T > GF
Definition: exprtk.hpp:18125
#define exprtk_register_function(FunctionName, FunctionType)
bool is_vector_eqineq_logic_operation(const details::operator_type &operation, expression_node_ptr(&branch)[2]) const
Definition: exprtk.hpp:26101
Definition: exprtk.hpp:6090
Definition: exprtk.hpp:4913
Definition: exprtk.hpp:6216
std::size_t size() const
Definition: exprtk.hpp:9728
static const std::size_t reserved_words_size
Definition: exprtk.hpp:426
void split(const std::string &s)
Definition: exprtk.hpp:23231
char_cptr base() const
Definition: exprtk.hpp:5618
expression_ptr initialiser_
Definition: exprtk.hpp:6345
Definition: exprtk.hpp:19262
T nequal_impl(const T v0, const T v1, int_type_tag)
Definition: exprtk.hpp:923
bool disable_vardef_
Definition: exprtk.hpp:19799
virtual node_type type() const
Definition: exprtk.hpp:4954
static bool parse_nan(Iterator &itr, const Iterator end, T &t)
Definition: exprtk.hpp:1753
operator_type operation() const
Definition: exprtk.hpp:13297
~binary_ext_node()
Definition: exprtk.hpp:5847
token_list_t token_list_
Definition: exprtk.hpp:2837
generic_type::string_view string_t
Definition: exprtk.hpp:37641
generic_type::scalar_view scalar_t
Definition: exprtk.hpp:38125
std::size_t process_stride_2(generator &g)
Definition: exprtk.hpp:3100
T0oT1oT2(node_type &)
Definition: exprtk.hpp:13836
static std::string id(expression_generator< Type > &expr_gen, const details::operator_type o0, const details::operator_type o1, const details::operator_type o2)
Definition: exprtk.hpp:33556
str_base_ptr str0_base_ptr_
Definition: exprtk.hpp:7978
T value(details::expression_node< T > *n)
Definition: exprtk.hpp:12217
std::size_t size() const
Definition: exprtk.hpp:4177
bool is_string_concat_node(const expression_node< T > *node)
Definition: exprtk.hpp:15346
Definition: exprtk.hpp:13159
axpyz()
Definition: exprtk.hpp:37935
std::vector< scope_element > element_
Definition: exprtk.hpp:18503
bool operator==(const symbol_table< T > &st) const
Definition: exprtk.hpp:16735
T2 t2() const
Definition: exprtk.hpp:13886
T abs_impl(const T v, real_type_tag)
Definition: exprtk.hpp:855
exprtk::igeneric_function< T > igfun_t
Definition: exprtk.hpp:37478
range_t * range_ptr
Definition: exprtk.hpp:8335
std::size_t get_variable_list(Sequence< std::pair< std::string, T >, Allocator > &vlist) const
Definition: exprtk.hpp:17259
Definition: exprtk.hpp:14321
expression_node< T > * expression_ptr
Definition: exprtk.hpp:15205
assignment_vecvec_op_node(const operator_type &opr, expression_ptr branch0, expression_ptr branch1)
Definition: exprtk.hpp:10183
vocovov_t::type4 node_type
Definition: exprtk.hpp:33286
expression_node< T >::node_type type() const
Definition: exprtk.hpp:8426
expression_node< typename node_type::value_type > * allocate_type(T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6) const
Definition: exprtk.hpp:15665
Definition: exprtk.hpp:19258
data_t data() const
Definition: exprtk.hpp:4683
std::map< std::string, std::pair< std::string, token::token_type >, details::ilesscompare > replace_map_t
Definition: exprtk.hpp:3557
T value() const
Definition: exprtk.hpp:8127
vector_view_impl(vector_view_t &vec_view)
Definition: exprtk.hpp:5354
Definition: exprtk.hpp:11409
const T c_
Definition: exprtk.hpp:14648
Definition: exprtk.hpp:12138
std::pair< expression_ptr, bool > branch_t
Definition: exprtk.hpp:14547
Definition: exprtk.hpp:13112
Definition: exprtk.hpp:4405
rebasevector_celem_node< T > * rbvec_node_ptr_
Definition: exprtk.hpp:10047
ifunction< T > ifunction_t
Definition: exprtk.hpp:18126
operator_type operation()
Definition: exprtk.hpp:5813
void rebase(data_ptr_t data)
Definition: exprtk.hpp:4082
sf4_var_node(const T &v0, const T &v1, const T &v2, const T &v3)
Definition: exprtk.hpp:9295
T value() const
Definition: exprtk.hpp:6796
settings_store & enable_all_assignment_ops()
Definition: exprtk.hpp:19347
bool join(const lexer::token &t0, const lexer::token &t1, lexer::token &t)
Definition: exprtk.hpp:3240
static T result(T v)
Definition: exprtk.hpp:1557
bool disable_rsrvd_sym_usr_
Definition: exprtk.hpp:19800
std::string get_stringvar_name(const expression_node_ptr &ptr) const
Definition: exprtk.hpp:18930
T & ref()
Definition: exprtk.hpp:7159
virtual expression_node< T > * move_branch(const std::size_t &index)=0
T second_derivative(const expression< T > &e, T &x, const T &h=T(0.00001))
Definition: exprtk.hpp:34907
opr_base< T >::Type Type
Definition: exprtk.hpp:12167
opr_base< T >::RefType RefType
Definition: exprtk.hpp:12019
Definition: exprtk.hpp:3074
generic_type::scalar_view scalar_t
Definition: exprtk.hpp:36952
settings_store settings_
Definition: exprtk.hpp:34652
void dump() const
Definition: exprtk.hpp:4703
expression_node< T > * expression_ptr
Definition: exprtk.hpp:9907
void free_element(scope_element &se)
Definition: exprtk.hpp:18430
vector_holder_t * vector_holder_ptr
Definition: exprtk.hpp:7134
static expression_node_ptr process(expression_generator< Type > &expr_gen, const details::operator_type &operation, expression_node_ptr(&branch)[2])
Definition: exprtk.hpp:31755
bool control_struct_enabled(const std::string &control_struct)
Definition: exprtk.hpp:19447
element_type
Definition: exprtk.hpp:18227
void load_unary_operations_map(unary_op_map_t &m)
Definition: exprtk.hpp:34457
results_context< T > results_context_t
Definition: exprtk.hpp:17597
parser< T > & parser_
Definition: exprtk.hpp:20739
details::variable_node< T > variable_t
Definition: exprtk.hpp:16582
vector_node_ptr vec() const
Definition: exprtk.hpp:10468
stringvar_node< T > * strvar_node_ptr
Definition: exprtk.hpp:8332
static std::string null_value
Definition: exprtk.hpp:7576
scoped_bft(BaseFuncType &bft)
Definition: exprtk.hpp:35726
const T1 const T2
Definition: exprtk.hpp:13650
exprtk::ifunction< T > function_t
Definition: exprtk.hpp:35496
std::size_t column_no
Definition: exprtk.hpp:17992
Definition: exprtk.hpp:17572
Definition: exprtk.hpp:13847
vov_node< T, Operation > & operator=(vov_node< T, Operation > &)
std::map< std::string, expression_t > expr_map_
Definition: exprtk.hpp:36128
static std::string id(expression_generator< Type > &expr_gen, const details::operator_type o0, const details::operator_type o1, const details::operator_type o2)
Definition: exprtk.hpp:32993
void insert_front(token_t::token_type tk_type)
Definition: exprtk.hpp:2299
vector_node(const vds_t &vds, vector_holder_t *vh)
Definition: exprtk.hpp:7017
Definition: exprtk.hpp:3949
std::size_t size() const
Definition: exprtk.hpp:8818
expression_node< T > * expression_ptr
Definition: exprtk.hpp:5460
Definition: exprtk.hpp:18107
std::size_t size() const
Definition: exprtk.hpp:4693
control_block()
Definition: exprtk.hpp:4553
T log10_impl(const T v, real_type_tag)
Definition: exprtk.hpp:1295
type_map_t::iterator tm_itr_t
Definition: exprtk.hpp:16213
vararg_varnode(const Sequence< expression_ptr, Allocator > &arg_list)
Definition: exprtk.hpp:9392
igfun_t::parameter_list_t parameter_list_t
Definition: exprtk.hpp:37479
void update(const T &v0, const T &v1, const T &v2, const T &v3)
Definition: exprtk.hpp:35531
range_t * range
Definition: exprtk.hpp:6966
bool is_constant_node(const std::string &symbol_name) const
Definition: exprtk.hpp:18766
T value() const
Definition: exprtk.hpp:14847
const std::size_t size_
Definition: exprtk.hpp:5314
vds_t vds_
Definition: exprtk.hpp:10660
Definition: exprtk.hpp:2026
Definition: exprtk.hpp:9633
value_ptr operator[](const std::size_t &index) const
Definition: exprtk.hpp:5257
static std::string id(expression_generator< Type > &expr_gen, const details::operator_type o0, const details::operator_type o1, const details::operator_type o2)
Definition: exprtk.hpp:32712
variable_node< T > * variable_node_ptr
Definition: exprtk.hpp:7317
str_base_ptr str0_base_ptr_
Definition: exprtk.hpp:8434
type_store< T > type_store_t
Definition: exprtk.hpp:4340
static T evaluate(const Type x, const Type c1, const Type c0)
Definition: exprtk.hpp:35289
T value() const
Definition: exprtk.hpp:9364
static expression_node_ptr process(expression_generator< Type > &expr_gen, const details::operator_type &operation, expression_node_ptr(&branch)[2])
Definition: exprtk.hpp:28352
generic_function_node< T, StringFunction > gen_function_t
Definition: exprtk.hpp:11607
print(const std::string &scalar_format="%10.5f")
Definition: exprtk.hpp:36517
Definition: exprtk.hpp:2022
void load_sf4_map(sf4_map_t &sf4_map)
Definition: exprtk.hpp:34584
Definition: exprtk.hpp:4915
T atanh_impl(const T v, real_type_tag)
Definition: exprtk.hpp:1288
range_pack< T > range_t
Definition: exprtk.hpp:7857
static expression_node_ptr process(expression_generator< Type > &, const details::operator_type &, expression_node_ptr(&)[2])
Definition: exprtk.hpp:30372
static T process(Type t1, Type t2)
Definition: exprtk.hpp:12043
data_type
Definition: exprtk.hpp:17567
#define extended_opr_switch_statements
Definition: exprtk.hpp:28020
settings_store & disable_local_vardef()
Definition: exprtk.hpp:19419
T3_ T3
Definition: exprtk.hpp:13857
std::pair< expression_ptr, bool > branch_t
Definition: exprtk.hpp:5891
Operation operation_t
Definition: exprtk.hpp:14452
SType0 s0_
Definition: exprtk.hpp:14755
static const std::size_t inequality_ops_list_size
Definition: exprtk.hpp:498
ifunction * function_
Definition: exprtk.hpp:11306
Operation operation_t
Definition: exprtk.hpp:14548
T max_impl(const T v0, const T v1, real_type_tag)
Definition: exprtk.hpp:867
Definition: exprtk.hpp:13240
~repeat_until_loop_node()
Definition: exprtk.hpp:6229
return_type
Definition: exprtk.hpp:15952
static std::string id(expression_generator< Type > &expr_gen, const details::operator_type o0, const details::operator_type o1, const details::operator_type o2)
Definition: exprtk.hpp:32355
vector_elem_node< T > * vec_node_ptr_
Definition: exprtk.hpp:9553
expression_ptr branch_
Definition: exprtk.hpp:5504
ts_list_t parameter_list_
Definition: exprtk.hpp:4381
T0oT1oT2oT3< T, T0, T1, T2, T3, ProcessMode > node_type
Definition: exprtk.hpp:13858
bool active
Definition: exprtk.hpp:18304
covoc_t::type0 node_type
Definition: exprtk.hpp:29897
static std::string id(expression_generator< Type > &expr_gen, const details::operator_type o0, const details::operator_type o1, const details::operator_type o2)
Definition: exprtk.hpp:31681
Definition: exprtk.hpp:4441
T1 t1_
Definition: exprtk.hpp:14022
strvar_node_ptr str1_node_ptr_
Definition: exprtk.hpp:8067
expression_node< T > * branch(const std::size_t &) const
Definition: exprtk.hpp:14693
Definition: exprtk.hpp:4421
static std::string id(expression_generator< Type > &expr_gen, const details::operator_type o0, const details::operator_type o1, const details::operator_type o2)
Definition: exprtk.hpp:33050
virtual bool process(const std::string &, usr_symbol_type &st, T &default_value, std::string &error_message)
Definition: exprtk.hpp:19022
freefunc08(ff08_functor ff)
Definition: exprtk.hpp:16108
~quaternary_node()
Definition: exprtk.hpp:5958
PowOp operation_t
Definition: exprtk.hpp:15206
expression_node< T > * move_branch(const std::size_t &)
Definition: exprtk.hpp:14698
vec_data_store< T > type
Definition: exprtk.hpp:4546
RangePack rp1_
Definition: exprtk.hpp:14882
vovov_t::type1 node_type
Definition: exprtk.hpp:29476
parser(const settings_t &settings=settings_t())
Definition: exprtk.hpp:19815
expression_node< T > * expression_ptr
Definition: exprtk.hpp:10669
token_list_itr_t token_itr_
Definition: exprtk.hpp:2838
settings_store & disable_all_base_functions()
Definition: exprtk.hpp:19365
Definition: exprtk.hpp:14132
bool token_is(const token_t::token_type &ttype, const std::string &value, const token_advance_mode mode=e_advance)
Definition: exprtk.hpp:4028
Definition: exprtk.hpp:18117
function_t * function_ptr
Definition: exprtk.hpp:16592
static void assign(RefType t1, Type t2)
Definition: exprtk.hpp:12033
expression_node_ptr conditional(expression_node_ptr condition, expression_node_ptr consequent, expression_node_ptr alternative) const
Definition: exprtk.hpp:26307
irange_t * irange_ptr
Definition: exprtk.hpp:8080
~cob_node()
Definition: exprtk.hpp:14607
T value() const
Definition: exprtk.hpp:7593
range_ptr str1_range_ptr_
Definition: exprtk.hpp:15072
T value() const
Definition: exprtk.hpp:8778
vector_holder(const vds_t &vds)
Definition: exprtk.hpp:5395
std::size_t error_index(const std::size_t &i)
Definition: exprtk.hpp:3534
dotk()
Definition: exprtk.hpp:38130
scope_element & get_element(const std::string &var_name, const std::size_t index=std::numeric_limits< std::size_t >::max())
Definition: exprtk.hpp:18344
#define else_stmt(N)
static std::string id(expression_generator< Type > &expr_gen, const details::operator_type o0, const details::operator_type o1, const details::operator_type o2)
Definition: exprtk.hpp:32243
static T_ execute(ifunction &f, T_(&v)[18])
Definition: exprtk.hpp:11176
exprtk_define_unary_op(abs) exprtk_define_unary_op(acos) exprtk_define_unary_op(acosh) exprtk_define_unary_op(asin) exprtk_define_unary_op(asinh) exprtk_define_unary_op(atan) exprtk_define_unary_op(atanh) exprtk_define_unary_op(ceil) exprtk_define_unary_op(cos) exprtk_define_unary_op(cosh) exprtk_define_unary_op(cot) exprtk_define_unary_op(csc) exprtk_define_unary_op(d2g) exprtk_define_unary_op(d2r) exprtk_define_unary_op(erf) exprtk_define_unary_op(erfc) exprtk_define_unary_op(exp) exprtk_define_unary_op(expm1) exprtk_define_unary_op(floor) exprtk_define_unary_op(frac) exprtk_define_unary_op(g2d) exprtk_define_unary_op(log) exprtk_define_unary_op(log10) exprtk_define_unary_op(log2) exprtk_define_unary_op(log1p) exprtk_define_unary_op(ncdf) exprtk_define_unary_op(neg) exprtk_define_unary_op(notl) exprtk_define_unary_op(pos) exprtk_define_unary_op(r2d) exprtk_define_unary_op(round) exprtk_define_unary_op(sec) exprtk_define_unary_op(sgn) exprtk_define_unary_op(sin) exprtk_define_unary_op(sinc) exprtk_define_unary_op(sinh) exprtk_define_unary_op(sqrt) exprtk_define_unary_op(tan) exprtk_define_unary_op(tanh) exprtk_define_unary_op(trunc) template< typename T > struct opr_base
Definition: exprtk.hpp:11925
expression_ptr incrementor_
Definition: exprtk.hpp:6577
type_view< char > string_view
Definition: exprtk.hpp:4268
T value() const
Definition: exprtk.hpp:15182
range_ptr str1_range_ptr_
Definition: exprtk.hpp:8571
std::size_t count() const
Definition: exprtk.hpp:4346
disabled_entity_set_t disabled_arithmetic_set_
Definition: exprtk.hpp:19806
ifunction< T > function_t
Definition: exprtk.hpp:16589
Definition: exprtk.hpp:15954
stringvar_node< T > * strvar_node_ptr
Definition: exprtk.hpp:7994
Definition: exprtk.hpp:17972
vector_node< T > * vector_node_ptr
Definition: exprtk.hpp:7007
expression_node< T > * expression_ptr
Definition: exprtk.hpp:14546
x y t t *t x y t t t x y t t t x *y t *t t x *y t *t t x y t t t x y t t t t(t/t)") define_sfop3(19
expression_node_ptr var_node
Definition: exprtk.hpp:18306
const T & v0_
Definition: exprtk.hpp:14387
static T process_2(const Sequence &arg_list)
Definition: exprtk.hpp:12334
Definition: exprtk.hpp:2023
T1 t1_
Definition: exprtk.hpp:13937
expression_node_ptr parse_repeat_until_loop()
Definition: exprtk.hpp:21632
parser_state()
Definition: exprtk.hpp:18959
vector_holder_base * vector_holder_base_
Definition: exprtk.hpp:5435
T exp_impl(const T v, real_type_tag)
Definition: exprtk.hpp:1292
Definition: exprtk.hpp:4141
range_pack< T > range_t
Definition: exprtk.hpp:8450
expression_node< T >::node_type type() const
Definition: exprtk.hpp:8300
expression_node< T > * expression_ptr
Definition: exprtk.hpp:9434
vovovov_t::type0 node_type
Definition: exprtk.hpp:30382
void scan_symbol()
Definition: exprtk.hpp:2561
expression_node_ptr synthesize_strogen_expression(const details::operator_type &opr, expression_node_ptr(&branch)[2])
Definition: exprtk.hpp:33968
virtual value_ptr value_at(const std::size_t &) const =0
vococ_t::type0 node_type
Definition: exprtk.hpp:30248
T value(T *t)
Definition: exprtk.hpp:12223
bool initialised_
Definition: exprtk.hpp:8221
std::vector< std::size_t > error_list_
Definition: exprtk.hpp:3550
expression_node< T >::node_type type() const
Definition: exprtk.hpp:13705
functor_t::bfunc_t binary_functor_t
Definition: exprtk.hpp:9005
std::map< std::string, std::pair< quaternary_functor_t, operator_t > > sf4_map_t
Definition: exprtk.hpp:18192
std::string & stringvar_ref(const std::string &symbol_name)
Definition: exprtk.hpp:16906
opr_base< T >::RefType RefType
Definition: exprtk.hpp:11995
functor_t::bfunc_t bfunc_t
Definition: exprtk.hpp:13762
Definition: exprtk.hpp:4428
igfun_t::parameter_list_t parameter_list_t
Definition: exprtk.hpp:36949
ff05_functor f
Definition: exprtk.hpp:16080
Definition: exprtk.hpp:11601
bool empty() const
Definition: exprtk.hpp:18331
opr_base< T >::Type Type
Definition: exprtk.hpp:12196
static T process(const std::string &t1, const std::string &t2)
Definition: exprtk.hpp:12104
igfun_t::generic_type generic_type
Definition: exprtk.hpp:37929
static details::operator_type operation()
Definition: exprtk.hpp:12213
vocovoc_t::sf4_type sf4_type
Definition: exprtk.hpp:32481
exprtk_register_real_type_tag(double) exprtk_register_real_type_tag(long double) exprtk_register_real_type_tag(float) exprtk_register_complex_type_tag(double) exprtk_register_complex_type_tag(long double) exprtk_register_complex_type_tag(float) exprtk_register_int_type_tag(short) exprtk_register_int_type_tag(int) exprtk_register_int_type_tag(long long int) exprtk_register_int_type_tag(unsigned short) exprtk_register_int_type_tag(unsigned int) exprtk_register_int_type_tag(unsigned long long int) template< typename T > struct epsilon_type
Definition: exprtk.hpp:776
scope_element()
Definition: exprtk.hpp:18244
Definition: exprtk.hpp:4457
expression_node< T > * expression_ptr
Definition: exprtk.hpp:11414
static T process_2(const Sequence &arg_list)
Definition: exprtk.hpp:12391
Definition: exprtk.hpp:4434
T0oT1oT2_sf3(T0 p0, T1 p1, T2 p2, const tfunc_t p3)
Definition: exprtk.hpp:13955
opr_base< T >::Type Type
Definition: exprtk.hpp:12018
Definition: exprtk.hpp:4409
bracket_checker()
Definition: exprtk.hpp:3411
expression_node_ptr return_envelope(expression_node_ptr body, results_context_t *rc, bool *&return_invoked)
Definition: exprtk.hpp:27393
bool parse_range(range_t &rp, const bool skip_lsqr=false)
Definition: exprtk.hpp:22600
const T & v1() const
Definition: exprtk.hpp:14380
Definition: exprtk.hpp:4404
expression_node_ptr parse_branch(precedence_level precedence=e_level00)
Definition: exprtk.hpp:25256
node_type & operator=(node_type &)
Definition: exprtk.hpp:14211
Definition: exprtk.hpp:38072
function_N_node(ifunction *func)
Definition: exprtk.hpp:11028
scope_element_manager sem_
Definition: exprtk.hpp:34671
Definition: exprtk.hpp:15955
expression_ptr final_node_
Definition: exprtk.hpp:8974
data_t & ref()
Definition: exprtk.hpp:4698
str_xrox_node(SType0 p0, SType1 p1, RangePack rp0)
Definition: exprtk.hpp:14773
static std::string id(expression_generator< Type > &expr_gen, const details::operator_type o0, const details::operator_type o1, const details::operator_type o2)
Definition: exprtk.hpp:32019
file_mode
Definition: exprtk.hpp:36591
vds_t & vds()
Definition: exprtk.hpp:7461
Operation operation_t
Definition: exprtk.hpp:14833
static T process(const std::string &t1, const std::string &t2)
Definition: exprtk.hpp:12114
T expm1_impl(const T v, real_type_tag)
Definition: exprtk.hpp:892
element_type type
Definition: exprtk.hpp:18303
ff01_functor f
Definition: exprtk.hpp:16040
expression_node< T >::node_type type() const
Definition: exprtk.hpp:15217
Definition: exprtk.hpp:12129
Definition: exprtk.hpp:4433
irange_t * irange_ptr
Definition: exprtk.hpp:7999
bool side_effect() const
Definition: exprtk.hpp:10311
Definition: exprtk.hpp:5440
parameter_list(std::vector< type_store > &pl)
Definition: exprtk.hpp:4168
expression_node< T > * expression_ptr
Definition: exprtk.hpp:8075
x y t t *t x y t t t x y t t t x *y t *t t x *y t *t t x y t t t x y t t t x(y/z)
static expression_node_ptr process(expression_generator< Type > &expr_gen, const details::operator_type &operation, expression_node_ptr(&branch)[2])
Definition: exprtk.hpp:33460
std::size_t cache_size() const
Definition: exprtk.hpp:6937
disabled_entity_set_t disabled_ctrl_set_
Definition: exprtk.hpp:19804
std::string get_vector_name(const vector_holder_ptr &ptr) const
Definition: exprtk.hpp:17396
cocov_t::type1 node_type
Definition: exprtk.hpp:30135
T0 t0_
Definition: exprtk.hpp:13839
void case_normalise(std::string &s)
Definition: exprtk.hpp:166
bool results_available_
Definition: exprtk.hpp:4380
results_context< T > results_context_t
Definition: exprtk.hpp:17792
Definition: exprtk.hpp:14653
Definition: exprtk.hpp:14327
generic_type::scalar_view scalar_t
Definition: exprtk.hpp:37980
static details::operator_type operation()
Definition: exprtk.hpp:12116
string_base_node< T > * strbase_ptr_t
Definition: exprtk.hpp:6956
bool is_true_impl(const T v)
Definition: exprtk.hpp:843
static T process_2(const Sequence &arg_list)
Definition: exprtk.hpp:12531
literal_node(const T &v)
Definition: exprtk.hpp:5514
type_store< T > type_store_t
Definition: exprtk.hpp:4272
Definition: exprtk.hpp:4911
std::string get_variable_name(const expression_ptr &ptr) const
Definition: exprtk.hpp:17391
generic_type::vector_view vector_t
Definition: exprtk.hpp:37108
expression_node_t * expression_node_ptr
Definition: exprtk.hpp:18239
Definition: exprtk.hpp:4438
Definition: exprtk.hpp:14028
shift_left()
Definition: exprtk.hpp:37534
const control_block::local_data_list_t & local_data_list()
Definition: exprtk.hpp:17886
generic_type::scalar_view scalar_t
Definition: exprtk.hpp:36459
const bool incrementor_deletable_
Definition: exprtk.hpp:6351
expression_node_ptr vararg_function(const details::operator_type &operation, Sequence< expression_node_ptr, Allocator > &arg_list)
Definition: exprtk.hpp:27136
bool is_sf3ext_node(const expression_node< T > *n)
Definition: exprtk.hpp:14118
std::list< std::string > local_stringvar_list_
Definition: exprtk.hpp:16651
range_t * range_ptr
Definition: exprtk.hpp:7858
Definition: exprtk.hpp:7568
details::T0oT1oT2< T, T0, T1, T2, typename T0oT1oT2process< T >::mode0 > type0
Definition: exprtk.hpp:14329
const T const_t
Definition: exprtk.hpp:18122
sf3_var_node< T, SpecialFunction > & operator=(sf3_var_node< T, SpecialFunction > &)
void * pointer
Definition: exprtk.hpp:17591
std::map< binary_functor_t, operator_t > inv_binary_op_map_t
Definition: exprtk.hpp:18194
virtual ~generic_function_node()
Definition: exprtk.hpp:11434
Definition: exprtk.hpp:36887
static T process_3(const Sequence &arg_list)
Definition: exprtk.hpp:12397
std::size_t process(generator &g)
Definition: exprtk.hpp:3082
range_t & range_ref()
Definition: exprtk.hpp:7696
bool to_int(IntType &i) const
Definition: exprtk.hpp:4294
Definition: exprtk.hpp:4429
Definition: exprtk.hpp:4451
std::size_t error_count() const
Definition: exprtk.hpp:20169
std::string value_
Definition: exprtk.hpp:8844
const T & operator[](const std::size_t index) const
Definition: exprtk.hpp:4105
virtual const T & v() const =0
bool result()
Definition: exprtk.hpp:3658
static void execute(T_(&v)[1], const branch_t(&b)[1])
Definition: exprtk.hpp:11150
Definition: exprtk.hpp:4443
std::vector< symbol_t > symbol_list_t
Definition: exprtk.hpp:19071
exprtk::details::numeric::details::number_type< T >::type num_type
Definition: exprtk.hpp:36462
expression_node< typename node_type::value_type > * allocate_type(T1 t1, T2 t2, T3 t3, T4 t4, T5 t5) const
Definition: exprtk.hpp:15654
write< T > w
Definition: exprtk.hpp:37047
T logn_impl(const T v0, const T v1, int_type_tag)
Definition: exprtk.hpp:959
bool vov_optimisable(const details::operator_type &operation, expression_node_ptr(&branch)[2]) const
Definition: exprtk.hpp:25877
const bool return_deletable_
Definition: exprtk.hpp:6140
generator()
Definition: exprtk.hpp:2194
void * data
Definition: exprtk.hpp:4161
Definition: exprtk.hpp:4442
Definition: exprtk.hpp:36594
expression_ptr branch_
Definition: exprtk.hpp:13439
str_base_ptr str1_base_ptr_
Definition: exprtk.hpp:15070
Definition: exprtk.hpp:12194
const T & v1()
Definition: exprtk.hpp:13356
Definition: exprtk.hpp:4455
std::string error() const
Definition: exprtk.hpp:20159
range_interface< T > irange_t
Definition: exprtk.hpp:7859
expression_ptr loop_body_
Definition: exprtk.hpp:6578
sequence_vector_impl operator=(const sequence_vector_impl &)
Definition: exprtk.hpp:4399
open< T > o
Definition: exprtk.hpp:37045
Definition: exprtk.hpp:18110
branch_t branch_[2]
Definition: exprtk.hpp:5831
bool assignment_disabled(const details::operator_type assignment_operation)
Definition: exprtk.hpp:19514
T value() const
Definition: exprtk.hpp:7206
std::vector< ptr_t > & vec_
Definition: exprtk.hpp:20806
Operation operation_t
Definition: exprtk.hpp:14720
static T process_1(const Sequence &arg_list)
Definition: exprtk.hpp:12591
expression_node< T > * expression_ptr
Definition: exprtk.hpp:7993
T value() const
Definition: exprtk.hpp:5518
~symbol_table()
Definition: exprtk.hpp:16711
Definition: exprtk.hpp:4401
synthesis_node_type_define(const T0 &, const T1 &, e_vov) synthesis_node_type_define(const T0 &
vector_node< T > * vector_node_ptr
Definition: exprtk.hpp:10331
static expression_node< T >::node_type type()
Definition: exprtk.hpp:12115
T nand_impl(const T v0, const T v1, int_type_tag)
Definition: exprtk.hpp:1118
T * vector_base_
Definition: exprtk.hpp:7305
Definition: exprtk.hpp:4407
bool unary_optimisable(const details::operator_type &operation) const
Definition: exprtk.hpp:25623
type make_error(const error_mode mode, const lexer::token &tk, const std::string &diagnostic="", const std::string &src_location="")
Definition: exprtk.hpp:18008
details::while_loop_node< T > while_loop_node_t
Definition: exprtk.hpp:18137
bipowninv_node(expression_ptr brnch)
Definition: exprtk.hpp:15239
generic_type::vector_view vector_t
Definition: exprtk.hpp:37482
exprtk::parser< Type > parser_t
Definition: exprtk.hpp:25442
T value() const
Definition: exprtk.hpp:9537
Definition: exprtk.hpp:4421
virtual ~ifunction()
Definition: exprtk.hpp:15846
Definition: exprtk.hpp:4441
std::string & s0()
Definition: exprtk.hpp:14868
expression_node< T >::node_type type() const
Definition: exprtk.hpp:5968
Definition: exprtk.hpp:4144
static T evaluate(const Type x, const Type c11, const Type c10, const Type c9, const Type c8, const Type c7, const Type c6, const Type c5, const Type c4, const Type c3, const Type c2, const Type c1, const Type c0)
Definition: exprtk.hpp:35173
~str_xroxr_node()
Definition: exprtk.hpp:14906
#define unary_opr_switch_statements
Definition: exprtk.hpp:26746
const bool test_deletable_
Definition: exprtk.hpp:6084
Definition: exprtk.hpp:4412
Definition: exprtk.hpp:37239
PowOp operation_t
Definition: exprtk.hpp:15237
range_pack< T > range_t
Definition: exprtk.hpp:6955
x y * z
Definition: exprtk.hpp:9025
std::size_t & min_num_args()
Definition: exprtk.hpp:15775
vector_holder_t * vector_holder_ptr
Definition: exprtk.hpp:7195
cons_conditional_node(expression_ptr test, expression_ptr consequent)
Definition: exprtk.hpp:6046
Definition: exprtk.hpp:8325
branch_t branch_[1]
Definition: exprtk.hpp:14538
static void print(const std::string &scalar_format, const scalar_t &s)
Definition: exprtk.hpp:36486
static bool is_binary(const expression< T > &expr)
Definition: exprtk.hpp:17943
Definition: exprtk.hpp:13389
vovov_t::sf3_type sf3_type
Definition: exprtk.hpp:29477
std::multimap< std::string, details::base_operation_t, details::ilesscompare > base_ops_map_t
Definition: exprtk.hpp:18195
bool register_joiner(lexer::token_joiner *joiner)
Definition: exprtk.hpp:3821
bool is_valid_sf_symbol(const std::string &symbol)
Definition: exprtk.hpp:241
Definition: exprtk.hpp:12204
static T_ execute(ifunction &f, T_(&v)[10])
Definition: exprtk.hpp:11232
const Type ctype
Definition: exprtk.hpp:25444
const generator_t & lexer() const
Definition: exprtk.hpp:3975
bool forward(const std::string &name, const std::size_t &arg_count, symbol_table_t &sym_table, const bool ret_present=false)
Definition: exprtk.hpp:36075
T value() const
Definition: exprtk.hpp:5670
std::string value_
Definition: exprtk.hpp:7983
static const std::string cntrl_struct_list[]
Definition: exprtk.hpp:469
str_base_ptr str_base_ptr_
Definition: exprtk.hpp:8977
expression_node< T >::node_type type() const
Definition: exprtk.hpp:14365
static T process(Type t1, Type t2)
Definition: exprtk.hpp:11996
settings_arithmetic_opr
Definition: exprtk.hpp:19288
branch_t branch_[1]
Definition: exprtk.hpp:14710
static expression_node< T > * allocate(Allocator &allocator, T0 p0, T1 p1, T2 p2, T3 p3, qfunc_t p4)
Definition: exprtk.hpp:14201
bool & b
Definition: exprtk.hpp:20837
switch_node(const Sequence< expression_ptr, Allocator > &arg_list)
Definition: exprtk.hpp:6595
exprtk::igeneric_function< T > igfun_t
Definition: exprtk.hpp:37243
vector_holder_ptr vec_node
Definition: exprtk.hpp:18307
Definition: exprtk.hpp:4460
static T process_4(const Sequence &arg_list)
Definition: exprtk.hpp:12775
irange_t * irange_ptr
Definition: exprtk.hpp:8453
std::string value
Definition: exprtk.hpp:2181
bool replacer_enabled() const
Definition: exprtk.hpp:19425
static expression_node_ptr process(expression_generator< Type > &expr_gen, const details::operator_type &operation, expression_node_ptr(&branch)[2])
Definition: exprtk.hpp:29419
exprtk::igeneric_function< T > igfun_t
Definition: exprtk.hpp:36948
Definition: exprtk.hpp:5542
vob_node< T, Operation > & operator=(const vob_node< T, Operation > &)
const T & v0_
Definition: exprtk.hpp:9317
T0oT1< T, T0, T1 > node_type
Definition: exprtk.hpp:13697
covovoc_t::type0 node_type
Definition: exprtk.hpp:31263
static expression_node_ptr process(expression_generator< Type > &expr_gen, const details::operator_type &operation, expression_node_ptr(&branch)[2])
Definition: exprtk.hpp:32617
range_interface< T > irange_t
Definition: exprtk.hpp:7731
Definition: exprtk.hpp:4406
bool init(const std::string &str)
Definition: exprtk.hpp:3956
std::pair< bool, std::size_t > n1_c
Definition: exprtk.hpp:6945
const type_store & front() const
Definition: exprtk.hpp:4197
Definition: exprtk.hpp:2029
std::map< operator_t, unary_functor_t > unary_op_map_t
Definition: exprtk.hpp:18187
Definition: exprtk.hpp:2021
void add_invalid_set1(lexer::token::token_type t)
Definition: exprtk.hpp:3709
expression_node_ptr parse_uninitialised_var_statement(const std::string &var_name)
Definition: exprtk.hpp:24343
static T evaluate(const Type x, const Type c3, const Type c2, const Type c1, const Type c0)
Definition: exprtk.hpp:35269
const Type & vtype
Definition: exprtk.hpp:25443
range_t * range_ptr
Definition: exprtk.hpp:7730
bool is_invalid_break_continue_op(expression_node_ptr(&branch)[2])
Definition: exprtk.hpp:26010
T and_opr(const T v0, const T v1)
Definition: exprtk.hpp:1482
T operator()(std::string &result, parameter_list_t parameters)
Definition: exprtk.hpp:37017
bool enable_numeric_check_
Definition: exprtk.hpp:19791
T value() const
Definition: exprtk.hpp:7671
data_t data()
Definition: exprtk.hpp:4678
exprtk::igeneric_function< T > igfun_t
Definition: exprtk.hpp:37430
ifunction< T > ifunction_t
Definition: exprtk.hpp:16201
uvouv_node(const T &var0, const T &var1, ufunc_t uf0, ufunc_t uf1, bfunc_t bf)
Definition: exprtk.hpp:13327
const bool initialiser_deletable_
Definition: exprtk.hpp:6579
Definition: exprtk.hpp:13046
igfun_t::parameter_list_t parameter_list_t
Definition: exprtk.hpp:37244
const bool body_deletable_
Definition: exprtk.hpp:11898
bool is_vararg_function(const std::string &vararg_function_name) const
Definition: exprtk.hpp:17375
expression_node< T >::node_type type() const
Definition: exprtk.hpp:7108
T0 t0() const
Definition: exprtk.hpp:13721
bool initialised_
Definition: exprtk.hpp:8840
T0 t0_
Definition: exprtk.hpp:14112
generic_function_node< T, GenericFunction > gen_function_t
Definition: exprtk.hpp:11690
static T_ execute(ifunction &f, T_(&v)[5])
Definition: exprtk.hpp:11267
vds_t vds_
Definition: exprtk.hpp:7235
expression_node< T > * expression_ptr
Definition: exprtk.hpp:5839
settings_store & disable_base_function(settings_base_funcs bf)
Definition: exprtk.hpp:19541
T3 t3() const
Definition: exprtk.hpp:13891
Definition: exprtk.hpp:4913
T logn_impl(const T v0, const T v1, real_type_tag)
Definition: exprtk.hpp:953
expression_node< T >::node_type type() const
Definition: exprtk.hpp:7330
std::string & s1()
Definition: exprtk.hpp:15110
static expression_node< T >::node_type type()
Definition: exprtk.hpp:12160
sort< T > st
Definition: exprtk.hpp:38177
Definition: exprtk.hpp:20748
vovovoc_t::sf4_type sf4_type
Definition: exprtk.hpp:33174
Operation operation_t
Definition: exprtk.hpp:13394
range_t range_
Definition: exprtk.hpp:7982
details::T0oT1< T, T0, T1 > type0
Definition: exprtk.hpp:14323
const bool condition_deletable_
Definition: exprtk.hpp:6413
Definition: exprtk.hpp:4450
Definition: exprtk.hpp:4450
Definition: exprtk.hpp:4447
details::switch_node< T > switch_node_t
Definition: exprtk.hpp:18145
null_eq_node(expression_ptr brnch, const bool equality=true)
Definition: exprtk.hpp:5462
#define register_binary_op(Op, BinaryFunctor)
Definition: exprtk.hpp:4447
bool is_false(const expression_node< T > *node)
Definition: exprtk.hpp:4991
bool logic_disabled(const std::string &logic_operation)
Definition: exprtk.hpp:19506
static expression_node_ptr process(expression_generator< Type > &expr_gen, const details::operator_type &operation, expression_node_ptr(&branch)[2])
Definition: exprtk.hpp:32093
Definition: exprtk.hpp:2025
static void execute(std::pair< expression_node< T > *, bool >(&branch)[N])
Definition: exprtk.hpp:5753
vds_t vds_
Definition: exprtk.hpp:10321
void register_local_data(void *data, const std::size_t &size=0, const std::size_t data_mode=0)
Definition: exprtk.hpp:17863
Definition: exprtk.hpp:7069
T value() const
Definition: exprtk.hpp:8502
Definition: exprtk.hpp:16083
expression_node< T >::node_type type() const
Definition: exprtk.hpp:10142
range_data_type()
Definition: exprtk.hpp:6958
std::string to_str(const details::operator_type &operation) const
Definition: exprtk.hpp:25765
#define parse_digit_2(d)
void perform_check()
Definition: exprtk.hpp:36795
bool empty() const
Definition: exprtk.hpp:18559
expression_node_ptr const_optimise_sf3(const details::operator_type &operation, expression_node_ptr(&branch)[3])
Definition: exprtk.hpp:26836
expression_node< T > * expression_ptr
Definition: exprtk.hpp:9485
T(* tfunc_t)(Type t0, Type t1, Type t2)
Definition: exprtk.hpp:2004
covovov_t::sf4_type sf4_type
Definition: exprtk.hpp:32367
virtual ~expression_node()
Definition: exprtk.hpp:4941
Definition: exprtk.hpp:4396
type_view< T > vector_view
Definition: exprtk.hpp:4267
details::rebasevector_elem_node< T > rebasevector_elem_node_t
Definition: exprtk.hpp:18148
bool is_invalid_string_op(const details::operator_type &operation, expression_node_ptr(&branch)[3])
Definition: exprtk.hpp:26040
static const std::size_t arithmetic_ops_list_size
Definition: exprtk.hpp:481
static std::string id(expression_generator< Type > &expr_gen, const details::operator_type o0, const details::operator_type o1, const details::operator_type o2)
Definition: exprtk.hpp:32768
bool valid_vararg_operation(const std::string &symbol)
Definition: exprtk.hpp:20236
expression_node_ptr synthesize_expression(const details::operator_type &operation, expression_node_ptr(&branch)[N])
Definition: exprtk.hpp:34284
Definition: exprtk.hpp:13148
vec_data_store< T > vds_t
Definition: exprtk.hpp:7135
static const double sqrt2
Definition: exprtk.hpp:747
Definition: exprtk.hpp:4421
for_loop_bc_node(expression_ptr initialiser, expression_ptr condition, expression_ptr incrementor, expression_ptr loop_body)
Definition: exprtk.hpp:6486
T xor_impl(const T v0, const T v1, int_type_tag)
Definition: exprtk.hpp:1154
exprtk::igeneric_function< T > igfun_t
Definition: exprtk.hpp:37977
details::string_literal_node< T > string_literal_node_t
Definition: exprtk.hpp:18154
irange_ptr str0_range_ptr_
Definition: exprtk.hpp:8842
Definition: exprtk.hpp:12721
static T_ execute(ifunction &f, T_(&v)[4])
Definition: exprtk.hpp:11274
usr_mode
Definition: exprtk.hpp:19007
vec_data_store< T > vds_t
Definition: exprtk.hpp:10672
Definition: exprtk.hpp:18225
~vob_node()
Definition: exprtk.hpp:14507
std::map< std::string, base_func * > funcparam_t
Definition: exprtk.hpp:35707
static control_block * create(const std::size_t &dsize, data_t data_ptr=data_t(0), bool dstrct=false)
Definition: exprtk.hpp:4584
expression_node_ptr string_function_call(igeneric_function_t *gf, std::vector< expression_node_ptr > &arg_list, const std::size_t &param_seq_index=std::numeric_limits< std::size_t >::max())
Definition: exprtk.hpp:27308
Definition: exprtk.hpp:4415
bool initialised_
Definition: exprtk.hpp:8976
T shl_impl(const T v0, const T v1, int_type_tag)
Definition: exprtk.hpp:1078
timer()
Definition: exprtk.hpp:36376
Definition: exprtk.hpp:35737
std::string entity_name(const PtrType &ptr) const
Definition: exprtk.hpp:16236
static T evaluate(const Type x, const Type c10, const Type c9, const Type c8, const Type c7, const Type c6, const Type c5, const Type c4, const Type c3, const Type c2, const Type c1, const Type c0)
Definition: exprtk.hpp:35186
settings_base_funcs
Definition: exprtk.hpp:19249
Definition: exprtk.hpp:11783
vector_assignment_node(T *vector_base, const std::size_t &size, const std::vector< expression_ptr > &initialiser_list, const bool single_value_initialse)
Definition: exprtk.hpp:7245
Definition: exprtk.hpp:4431
static T result(T v)
Definition: exprtk.hpp:1561
#define exprtk_define_freefunction(NN)
Definition: exprtk.hpp:17057
T value() const
Definition: exprtk.hpp:15090
Definition: exprtk.hpp:4396
vector_interface< T > * ivector_ptr
Definition: exprtk.hpp:13048
Definition: exprtk.hpp:23129
virtual ~sos_base_node()
Definition: exprtk.hpp:13230
Definition: exprtk.hpp:4403
Definition: exprtk.hpp:4435
generic_type::string_view string_t
Definition: exprtk.hpp:36894
expression_node< T >::node_type type() const
Definition: exprtk.hpp:6075
string_base_node< T > * str_base_ptr
Definition: exprtk.hpp:7995
bool is_negate_node(const expression_node< T > *node)
Definition: exprtk.hpp:5125
T and_impl(const T v0, const T v1, int_type_tag)
Definition: exprtk.hpp:1106
symbol_table< T > & operator=(const symbol_table< T > &st)
Definition: exprtk.hpp:16722
static expression_node_ptr process(expression_generator< Type > &expr_gen, const details::operator_type &operation, expression_node_ptr(&branch)[2])
Definition: exprtk.hpp:32036
Definition: exprtk.hpp:13445
expression_node< T >::node_type type() const
Definition: exprtk.hpp:8244
expression_node< T > * expression_ptr
Definition: exprtk.hpp:14657
expression_ptr branch_
Definition: exprtk.hpp:8307
expression_generator< T > expression_generator_
Definition: exprtk.hpp:34653
virtual ~voc_base_node()
Definition: exprtk.hpp:13134
const T & v_
Definition: exprtk.hpp:14587
Definition: exprtk.hpp:37001
vector_holder_t * vector_holder_ptr
Definition: exprtk.hpp:16882
expression_node< T >::node_type type() const
Definition: exprtk.hpp:15095
exprtk::expression< T > expression_t
Definition: exprtk.hpp:35395
settings_store & enable_base_function(settings_base_funcs bf)
Definition: exprtk.hpp:19619
Definition: exprtk.hpp:4908
T neg_impl(const T v, real_type_tag)
Definition: exprtk.hpp:1297
Definition: exprtk.hpp:4400
settings_store & disable_control_structure(settings_control_structs ctrl_struct)
Definition: exprtk.hpp:19554
static void destroy(control_block *&cntrl_blck)
Definition: exprtk.hpp:17659
expression_node< T >::node_type type() const
Definition: exprtk.hpp:5929
Operation operation_t
Definition: exprtk.hpp:14896
details::functor_t< T > functor_t
Definition: exprtk.hpp:13463
generic_function_ptr get_generic_function(const std::string &function_name) const
Definition: exprtk.hpp:18703
Operation operation_t
Definition: exprtk.hpp:14352
void print_type(const std::string &fmt, const T v, exprtk::details::numeric::details::real_type_tag)
Definition: exprtk.hpp:36447
expression_node< T > * expression_ptr
Definition: exprtk.hpp:9260
static T process(const Sequence< Type, Allocator > &arg_list)
Definition: exprtk.hpp:12303
Definition: exprtk.hpp:5456
expression_node< T > * branch(const std::size_t &) const
Definition: exprtk.hpp:14577
T value() const
Definition: exprtk.hpp:7093
void scan_special_function()
Definition: exprtk.hpp:2699
Definition: exprtk.hpp:4431
Definition: exprtk.hpp:2013
static expression_node_ptr process(expression_generator< Type > &expr_gen, const details::operator_type &operation, expression_node_ptr(&branch)[2])
Definition: exprtk.hpp:31981
details::cons_conditional_str_node< T > cons_conditional_str_node_t
Definition: exprtk.hpp:18162
Definition: exprtk.hpp:4397
expression_node< T >::node_type type() const
Definition: exprtk.hpp:15187
T value() const
Definition: exprtk.hpp:5963
const T & type
Definition: exprtk.hpp:35495
T nand_impl(const T v0, const T v1, real_type_tag)
Definition: exprtk.hpp:1112
std::string to_str(const StringView &view)
Definition: exprtk.hpp:4322
const T & cref_t
Definition: exprtk.hpp:18121
polynomial()
Definition: exprtk.hpp:35300
void update(const T &v0, const T &v1, const T &v2, const T &v3, const T &v4)
Definition: exprtk.hpp:35537
virtual bool process(const std::string &, symbol_table_t &, std::string &)
Definition: exprtk.hpp:19037
static const double pi_180
Definition: exprtk.hpp:742
std::pair< std::size_t, std::size_t > cached_range_t
Definition: exprtk.hpp:6828
Definition: exprtk.hpp:4400
static const expression_node< T >::node_type result
Definition: exprtk.hpp:13639
static bool process(parameter_list_t &parameters, std::size_t &r0, std::size_t &r1, const std::size_t &r0_prmidx, const std::size_t &r1_prmidx, const std::size_t vec_idx=0)
Definition: exprtk.hpp:37110
#define igeneric_function_empty_body(N)
Definition: exprtk.hpp:15970
Definition: exprtk.hpp:12561
range_ptr str0_range_ptr_
Definition: exprtk.hpp:8219
static expression_node_ptr process(expression_generator< Type > &expr_gen, const details::operator_type &operation, expression_node_ptr(&branch)[2])
Definition: exprtk.hpp:30590
static T process(Type t1, Type t2)
Definition: exprtk.hpp:12103
Definition: exprtk.hpp:18508
std::size_t size() const
Definition: exprtk.hpp:7608
static T process(const T &, const T &)
Definition: exprtk.hpp:12197
T log1p_impl(const T v, real_type_tag)
Definition: exprtk.hpp:965
igfun_t::generic_type generic_type
Definition: exprtk.hpp:37791
details::conditional_string_node< T > conditional_string_node_t
Definition: exprtk.hpp:18161
Definition: exprtk.hpp:4415
range_t range() const
Definition: exprtk.hpp:7691
assignment_vec_elem_node(const operator_type &opr, expression_ptr branch0, expression_ptr branch1)
Definition: exprtk.hpp:9525
static T process(const arg_list_t &arg)
Definition: exprtk.hpp:26676
static details::operator_type operation()
Definition: exprtk.hpp:12170
vovovov_t::sf4_type sf4_type
Definition: exprtk.hpp:33118
bool return_present_
Definition: exprtk.hpp:19213
void copy(const dependency_graph::Selection &selection)
Definition: actions.cpp:194
void init(possumwood::Metadata &meta)
Definition: asf.cpp:417
operator_type operation_
Definition: exprtk.hpp:5699
bool remove_vector(const std::string &vector_name)
Definition: exprtk.hpp:17217
Definition: exprtk.hpp:4448
Definition: exprtk.hpp:14336
~scoped_bool_negator()
Definition: exprtk.hpp:20819
Definition: exprtk.hpp:4430
getline< T > g
Definition: exprtk.hpp:37049
Definition: exprtk.hpp:37285
bool run_joiners(lexer::generator &g)
Definition: exprtk.hpp:3871
exprtk::igeneric_function< T > igfun_t
Definition: exprtk.hpp:37104
bool strength_reduction_enabled_
Definition: exprtk.hpp:34360
bool equality_
Definition: exprtk.hpp:5506
branch_t branch_[1]
Definition: exprtk.hpp:15197
vocov_t::sf3_type sf3_type
Definition: exprtk.hpp:29718
expression_node< T > * expression_ptr
Definition: exprtk.hpp:11849
T2 t2() const
Definition: exprtk.hpp:14084
static T process(Type t1, Type t2)
Definition: exprtk.hpp:12150
igfun_t::generic_type generic_type
Definition: exprtk.hpp:37382
expression_node_ptr const_optimise_mswitch(Sequence< expression_node_ptr, Allocator > &arg_list)
Definition: exprtk.hpp:26567
static void execute(T_(&v)[4], const branch_t(&b)[4])
Definition: exprtk.hpp:11117
Definition: exprtk.hpp:4413
virtual ~ivariable()
Definition: exprtk.hpp:6768
#define register_sf4(Op)
for_loop_node(expression_ptr initialiser, expression_ptr condition, expression_ptr incrementor, expression_ptr loop_body)
Definition: exprtk.hpp:6275
T value() const
Definition: exprtk.hpp:13409
virtual range_t & range_ref()=0
Definition: exprtk.hpp:2027
bool operation_optimisable(const details::operator_type &operation) const
Definition: exprtk.hpp:25791
T value() const
Definition: exprtk.hpp:8287
bool uvouv_optimisable(const details::operator_type &operation, expression_node_ptr(&branch)[2]) const
Definition: exprtk.hpp:25936
vector_node_ptr vec1_node_ptr_
Definition: exprtk.hpp:10812
Definition: exprtk.hpp:18114
cons_conditional_str_node(expression_ptr test, expression_ptr consequent)
Definition: exprtk.hpp:8747
const T & v() const
Definition: exprtk.hpp:14475
expression_node_ptr while_loop(expression_node_ptr &condition, expression_node_ptr &branch, const bool brkcont=false) const
Definition: exprtk.hpp:26404
const bfunc_t f0_
Definition: exprtk.hpp:13842
const T1 const T2 const T3
Definition: exprtk.hpp:13672
T pos_impl(const T v, real_type_tag)
Definition: exprtk.hpp:1298
const value_t * end() const
Definition: exprtk.hpp:4253
std::string file_name
Definition: exprtk.hpp:36609
Operation operation_t
Definition: exprtk.hpp:14598
expression_node< typename node_type::value_type > * allocate_c(const T1 &t1) const
Definition: exprtk.hpp:15468
binary_op_map_t binary_op_map_
Definition: exprtk.hpp:34666
const bool loop_body_deletable_
Definition: exprtk.hpp:6212
expression_node< T > * expression_ptr
Definition: exprtk.hpp:5945
std::size_t get_stringvar_list(Sequence< std::pair< std::string, std::string >, Allocator > &svlist) const
Definition: exprtk.hpp:17280
Definition: exprtk.hpp:4399
T value_type
Definition: exprtk.hpp:14049
static details::operator_type operation()
Definition: exprtk.hpp:12076
range_pack< T > range_t
Definition: exprtk.hpp:7488
expression_node< T > * expression_ptr
Definition: exprtk.hpp:14596
generic_type::scalar_view scalar_t
Definition: exprtk.hpp:38079
Definition: exprtk.hpp:4439
ViewType value_t
Definition: exprtk.hpp:4223
Definition: exprtk.hpp:16184
any_false< T > nf
Definition: exprtk.hpp:38170
~scoped_bft()
Definition: exprtk.hpp:35727
virtual ~string_range_node()
Definition: exprtk.hpp:7583
details::vector_holder< T > vector_holder_t
Definition: exprtk.hpp:16583
T value() const
Definition: exprtk.hpp:14673
range_interface< T > irange_t
Definition: exprtk.hpp:8336
void * stream_ptr
Definition: exprtk.hpp:36607
void * data
Definition: exprtk.hpp:18305
const vds_t & vds() const
Definition: exprtk.hpp:7052
Definition: exprtk.hpp:36533
settings_store & enable_control_structure(settings_control_structs ctrl_struct)
Definition: exprtk.hpp:19637
stringvar_t * stringvar_ptr
Definition: exprtk.hpp:16587
std::string name_
Definition: exprtk.hpp:35486
static const std::size_t logic_ops_list_size
Definition: exprtk.hpp:467
details::rebasevector_celem_node< T > rebasevector_celem_node_t
Definition: exprtk.hpp:18149
swap_node(variable_node_ptr var0, variable_node_ptr var1)
Definition: exprtk.hpp:7319
T logn(const T v0, const T v1)
Definition: exprtk.hpp:1433
Definition: exprtk.hpp:4443
Definition: exprtk.hpp:4912
bool state_
Definition: exprtk.hpp:3485
Definition: exprtk.hpp:4899
Definition: exprtk.hpp:1992
std::string error_line
Definition: exprtk.hpp:17990
bool valid(const std::string &name, const std::size_t &arg_count) const
Definition: exprtk.hpp:36062
std::map< operator_t, binary_functor_t > binary_op_map_t
Definition: exprtk.hpp:18188
Definition: exprtk.hpp:37426
bool final_deletable_
Definition: exprtk.hpp:8975
expression_ptr consequent_
Definition: exprtk.hpp:6083
Definition: exprtk.hpp:4424
type_view(type_store_t &ts)
Definition: exprtk.hpp:4225
T value() const
Definition: exprtk.hpp:7910
expression_node< T >::node_type type() const
Definition: exprtk.hpp:6132
bool logic_enabled(const std::string &logic_operation)
Definition: exprtk.hpp:19455
void remove_last_error()
Definition: exprtk.hpp:34376
T1_ T1
Definition: exprtk.hpp:13855
bool collect_variables_enabled() const
Definition: exprtk.hpp:19432
bool valid_symbol(const std::string &symbol, const bool check_reserved_symb=true) const
Definition: exprtk.hpp:17484
T2 t2_
Definition: exprtk.hpp:14215
generic_type::vector_view vector_t
Definition: exprtk.hpp:37883
static const std::size_t base_function_list_size
Definition: exprtk.hpp:460
void lodge_assignment(symbol_type cst, expression_node_ptr node)
Definition: exprtk.hpp:27511
std::string str() const
Definition: exprtk.hpp:11653
bool invalid_bracket_check(lexer::token::token_type base, lexer::token::token_type t)
Definition: exprtk.hpp:3728
bool return_stmt_present
Definition: exprtk.hpp:18990
Definition: exprtk.hpp:36595
Definition: exprtk.hpp:4919
Definition: exprtk.hpp:4459
details::functor_t< T > functor_t
Definition: exprtk.hpp:13323
Definition: exprtk.hpp:4435
bool arithmetic_disabled(const details::operator_type arithmetic_operation)
Definition: exprtk.hpp:19523
Definition: exprtk.hpp:4916
Definition: exprtk.hpp:13254
static expression_node_ptr process(expression_generator< Type > &expr_gen, const details::operator_type &operation, expression_node_ptr(&branch)[2])
Definition: exprtk.hpp:29479
scalar_view(const type_store_t &ts)
Definition: exprtk.hpp:4279
exprtk::igeneric_function< T > igfun_t
Definition: exprtk.hpp:37879
bool is_error() const
Definition: exprtk.hpp:2169
bool is_t0ot1ot2_node(const expression_node< T > *node)
Definition: exprtk.hpp:15298
static expression_node_ptr process(expression_generator< Type > &expr_gen, const details::operator_type &operation, expression_node_ptr(&branch)[2])
Definition: exprtk.hpp:33293
numeric_checker()
Definition: exprtk.hpp:3496
expression_node< typename node_type::value_type > * allocate(T1 &t1) const
Definition: exprtk.hpp:15462
void restore()
Definition: exprtk.hpp:2253
freefunc05(ff05_functor ff)
Definition: exprtk.hpp:16077
const T & v_
Definition: exprtk.hpp:15160
void copy(const var_t &src_v, varref_t &dest_v)
Definition: exprtk.hpp:35639
Definition: exprtk.hpp:12050
virtual ~base_func()
Definition: exprtk.hpp:35512
T2 t2() const
Definition: exprtk.hpp:14175
eof()
Definition: exprtk.hpp:37030
details::scor_node< T > scor_node_t
Definition: exprtk.hpp:18171
vector_node_ptr vec()
Definition: exprtk.hpp:10137
static const std::size_t cntrl_struct_list_size
Definition: exprtk.hpp:474
static T_ execute(ifunction &f, T_(&v)[1])
Definition: exprtk.hpp:11295
expression_node< T > * expression_ptr
Definition: exprtk.hpp:11024
type_store< ifunction< T >, ifunction< T > > function_store
Definition: exprtk.hpp:16607
operator_type operation() const
Definition: exprtk.hpp:13711
Definition: exprtk.hpp:4922
expression_node_ptr parse_expression(precedence_level precedence=e_level00)
Definition: exprtk.hpp:20409
virtual ~vector_interface()
Definition: exprtk.hpp:6983
expression_node< T > * branch(const std::size_t &index=0) const
Definition: exprtk.hpp:5870
const bool condition_deletable_
Definition: exprtk.hpp:6580
expression_t compile(const std::string &expression_string, symbol_table_t &symtab)
Definition: exprtk.hpp:20012
Definition: exprtk.hpp:4909
covocov_t::type1 node_type
Definition: exprtk.hpp:31917
settings_store & enable_all_control_structures()
Definition: exprtk.hpp:19329
type_ptr get_from_varptr(const void *ptr) const
Definition: exprtk.hpp:16435
virtual bool init_branches()
Definition: exprtk.hpp:11439
irange_t * irange_ptr
Definition: exprtk.hpp:8337
vovocov_t::type2 node_type
Definition: exprtk.hpp:32254
file_mode get_file_mode(const std::string &access)
Definition: exprtk.hpp:36752
bool add_vector(const std::string &vector_name, T *v, const std::size_t &v_size)
Definition: exprtk.hpp:17140
T0 t0() const
Definition: exprtk.hpp:13978
T0oT1< T, T0, T1 > & operator=(T0oT1< T, T0, T1 > &)
Definition: exprtk.hpp:13749
static T process(Type t1, Type t2)
Definition: exprtk.hpp:12113
Definition: exprtk.hpp:8318
expression_node_ptr synthesize_srocsr_expression(const details::operator_type &opr, expression_node_ptr(&branch)[2])
Definition: exprtk.hpp:33850
std::string branch_to_id(expression_node_ptr branch)
Definition: exprtk.hpp:25813
details::T0oT1oT2_define< T, cref_t, const_t, cref_t > vocov_t
Definition: exprtk.hpp:18204
Definition: exprtk.hpp:4915
static T process(Type t1, Type t2)
Definition: exprtk.hpp:12063
void create_data()
Definition: exprtk.hpp:4623
Definition: exprtk.hpp:4427
std::string remaining() const
Definition: exprtk.hpp:2321
settings_store & enable_logic_operation(settings_logic_opr logic)
Definition: exprtk.hpp:19655
const vds_t & vds() const
Definition: exprtk.hpp:9888
static const double e
Definition: exprtk.hpp:738
expression_node_ptr synthesize_vecarithmetic_operation_expression(const details::operator_type &operation, expression_node_ptr(&branch)[2])
Definition: exprtk.hpp:27832
T operator()(const std::size_t &ps_index, parameter_list_t parameters)
Definition: exprtk.hpp:36961
static const expression_node< T >::node_type result
Definition: exprtk.hpp:13617
void clear_stack()
Definition: exprtk.hpp:35685
static std::string id(expression_generator< Type > &expr_gen, const details::operator_type o0, const details::operator_type o1, const details::operator_type o2)
Definition: exprtk.hpp:30740
static bool compile(expression_generator< Type > &expr_gen, const std::string &id, T0 t0, T1 t1, T2 t2, T3 t3, expression_node_ptr &result)
Definition: exprtk.hpp:29269
Definition: exprtk.hpp:4911
vector_node_ptr temp_vec_node_
Definition: exprtk.hpp:10503
bool is_digit(const char_t c)
Definition: exprtk.hpp:122
expression_ptr expr
Definition: exprtk.hpp:17676
virtual ~vov_base_node()
Definition: exprtk.hpp:13098
str_xoxr_node< T, SType0, SType1, RangePack, Operation > & operator=(str_xoxr_node< T, SType0, SType1, RangePack, Operation > &)
Definition: exprtk.hpp:19254
T max(const T v0, const T v1)
Definition: exprtk.hpp:1398
expression_node< T >::node_type type() const
Definition: exprtk.hpp:14058
T value() const
Definition: exprtk.hpp:10870
vocovoc_t::type4 node_type
Definition: exprtk.hpp:33453
void clear()
Definition: exprtk.hpp:18279
Definition: exprtk.hpp:4422
vovoc_t::type1 node_type
Definition: exprtk.hpp:29597
Definition: exprtk.hpp:4405
static expression_node_ptr process(expression_generator< Type > &expr_gen, const details::operator_type &operation, expression_node_ptr(&branch)[2])
Definition: exprtk.hpp:32261
void init_precompilation()
Definition: exprtk.hpp:19853
virtual int insert(const token &, token &) token_inserter_empty_body inline virtual int insert(const token &
bool is_whitespace(const char_t c)
Definition: exprtk.hpp:93
bool function_enabled(const std::string &function_name)
Definition: exprtk.hpp:19439
std::size_t size() const
Definition: exprtk.hpp:7528
Definition: exprtk.hpp:6684
static T_ execute(ifunction &f, T_(&v)[14])
Definition: exprtk.hpp:11204
static expression_node_ptr process(expression_generator< Type > &expr_gen, const details::operator_type &operation, expression_node_ptr(&branch)[2])
Definition: exprtk.hpp:32373
T value() const
Definition: exprtk.hpp:13336
bool run_inserters(lexer::generator &g)
Definition: exprtk.hpp:3893
generic_type::vector_view vector_t
Definition: exprtk.hpp:37530
expression_node< T >::node_type type() const
Definition: exprtk.hpp:7037
Definition: exprtk.hpp:13550
Definition: exprtk.hpp:13504
void destroy_node(expression_node< T > *&node)
Definition: exprtk.hpp:5236
ror< T > rr
Definition: exprtk.hpp:38174
freefunc04(ff04_functor ff)
Definition: exprtk.hpp:16067
details::variable_node< T > variable_node_t
Definition: exprtk.hpp:16200
bool enable_bracket_check_
Definition: exprtk.hpp:19792
SType0 s0_
Definition: exprtk.hpp:14955
expression_node_ptr synthesize_csrocs_expression(const details::operator_type &opr, expression_node_ptr(&branch)[2])
Definition: exprtk.hpp:33940
T tan_impl(const T v, real_type_tag)
Definition: exprtk.hpp:1302
Definition: exprtk.hpp:4395
parser_t & parser_
Definition: exprtk.hpp:18542
Definition: exprtk.hpp:19307
stringvar_size_node()
Definition: exprtk.hpp:8231
Definition: exprtk.hpp:197
Definition: exprtk.hpp:4910
virtual void set_c(const T)=0
static expression_node< T >::node_type type()
Definition: exprtk.hpp:12212
settings_store & settings()
Definition: exprtk.hpp:20146
expression_node< typename node_type::value_type > * allocate(const T1 &t1, const T2 &t2, const T3 &t3, const T4 &t4, const T5 &t5) const
Definition: exprtk.hpp:15563
T value() const
Definition: exprtk.hpp:13287
static std::string to_str(token_type t)
Definition: exprtk.hpp:2122
T value() const
Definition: exprtk.hpp:9575
expression_node_ptr parse_symbol()
Definition: exprtk.hpp:25148
igeneric_function< T > igeneric_function_t
Definition: exprtk.hpp:18128
~str_vararg_node()
Definition: exprtk.hpp:8914
Definition: exprtk.hpp:12147
bool voc_optimisable(const details::operator_type &operation, expression_node_ptr(&branch)[2]) const
Definition: exprtk.hpp:25868
Definition: exprtk.hpp:2017
bool remove_variable(const std::string &variable_name, const bool delete_node=true)
Definition: exprtk.hpp:17183
static std::string id()
Definition: exprtk.hpp:13916
~binary_node()
Definition: exprtk.hpp:5795
std::size_t size() const
Definition: exprtk.hpp:18326
~st_data()
Definition: exprtk.hpp:16626
T operator()(const std::size_t &ps_index, parameter_list_t parameters)
Definition: exprtk.hpp:37598
expression_node< T > * expression_ptr
Definition: exprtk.hpp:6688
const bool consequent_deletable_
Definition: exprtk.hpp:6085
operator_type operation() const
Definition: exprtk.hpp:5682
Definition: exprtk.hpp:4460
str_vararg_node(const Sequence< expression_ptr, Allocator > &arg_list)
Definition: exprtk.hpp:8866
const T & ref() const
Definition: exprtk.hpp:7103
details::expression_node< T > * expression_ptr
Definition: exprtk.hpp:17561
collect_type
Definition: exprtk.hpp:19045
sf4_var_node< T, SpecialFunction > & operator=(sf4_var_node< T, SpecialFunction > &)
#define empty_method_body
Definition: exprtk.hpp:15849
static expression_node< T >::node_type type()
Definition: exprtk.hpp:12075
Definition: exprtk.hpp:14967
static void process(std::pair< expression_node< T > *, bool >(&)[N], expression_node< T > *)
Definition: exprtk.hpp:5708
char_cptr base() const
Definition: exprtk.hpp:8813
~control_block()
Definition: exprtk.hpp:17615
symbol_table_t::stringvar_ptr stringvar_ptr
Definition: exprtk.hpp:18553
static T process(const std::string &t1, const std::string &t2)
Definition: exprtk.hpp:12198
expression_node< T > * expression_ptr
Definition: exprtk.hpp:9523
std::deque< var_t > local_stack
Definition: exprtk.hpp:35704
assignment_rebasevec_celem_op_node(const operator_type &opr, expression_ptr branch0, expression_ptr branch1)
Definition: exprtk.hpp:10020
void lodge_symbol(const std::string &symbol, const symbol_type st)
Definition: exprtk.hpp:22775
voc_node< T, Operation > & operator=(const voc_node< T, Operation > &)
expression_node< T > * branch(const std::size_t &) const
Definition: exprtk.hpp:14632
generic_type::vector_view vector_t
Definition: exprtk.hpp:37981
irange_t * irange_ptr
Definition: exprtk.hpp:8586
T tanh_impl(const T v, real_type_tag)
Definition: exprtk.hpp:1303
symbol_table< T > symbol_table_t
Definition: exprtk.hpp:18175
bool return_invoked() const
Definition: exprtk.hpp:17805
const std::string & ref() const
Definition: exprtk.hpp:7538
settings_store & enable_arithmetic_operation(settings_arithmetic_opr arithmetic)
Definition: exprtk.hpp:19673
Definition: exprtk.hpp:13690
T value() const
Definition: exprtk.hpp:7510
str_base_ptr str1_base_ptr_
Definition: exprtk.hpp:8435
T sin_impl(const T v, real_type_tag)
Definition: exprtk.hpp:1299
char_cptr base() const
Definition: exprtk.hpp:7950
details::functor_t< T > functor_t
Definition: exprtk.hpp:13506
bool register_package(exprtk::symbol_table< T > &symtab)
Definition: exprtk.hpp:38189
vector_node< T > * vec0_node_ptr_
Definition: exprtk.hpp:9895
ff14_functor f
Definition: exprtk.hpp:16181
data_pack(void *ptr, const data_type dt, const std::size_t sz=0)
Definition: exprtk.hpp:17585
const bool consequent_deletable_
Definition: exprtk.hpp:6034
sequence_validator()
Definition: exprtk.hpp:3631
irange_t * irange_ptr
Definition: exprtk.hpp:8862
std::size_t size() const
Definition: exprtk.hpp:10483
bool is_letter(const char_t c)
Definition: exprtk.hpp:116
bool is_invalid_arithmetic_operation(const details::operator_type operation)
Definition: exprtk.hpp:20263
~for_loop_node()
Definition: exprtk.hpp:6289
expression_node< typename node_type::value_type > * allocate(const T1 &t1, const T2 &t2, const T3 &t3, const T4 &t4) const
Definition: exprtk.hpp:15554
static T process_4(const Sequence &arg_list)
Definition: exprtk.hpp:12403
details::T0oT1oT2oT3_define< T, const_t, cref_t, cref_t, const_t > covovoc_t
Definition: exprtk.hpp:18218
details(const std::size_t &vsize, const unsigned int loop_batch_size=global_loop_batch_size)
Definition: exprtk.hpp:4512
Definition: exprtk.hpp:4415
char_cptr base() const
Definition: exprtk.hpp:8947
bool create_stringvar(const std::string &stringvar_name, const std::string &value=std::string(""))
Definition: exprtk.hpp:16958
operator_type
Definition: exprtk.hpp:4391
static std::string id(expression_generator< Type > &expr_gen, const details::operator_type o0, const details::operator_type o1, const details::operator_type o2)
Definition: exprtk.hpp:31849
covov_t::sf3_type sf3_type
Definition: exprtk.hpp:29778
std::vector< lvarref_t > lvr_vec_t
Definition: exprtk.hpp:35500
generic_type::vector_view vector_t
Definition: exprtk.hpp:37384
value_t * data_
Definition: exprtk.hpp:4264
vds_t & vds()
Definition: exprtk.hpp:9733
range_t & range_ref()
Definition: exprtk.hpp:7960
local_data_t & local_data()
Definition: exprtk.hpp:17538
opr_base< T >::Type Type
Definition: exprtk.hpp:12206
T value() const
Definition: exprtk.hpp:9411
bool is_string_ccondition_node(const expression_node< T > *node)
Definition: exprtk.hpp:15364
freefunc13(ff13_functor ff)
Definition: exprtk.hpp:16164
functor_t::tfunc_t tfunc_t
Definition: exprtk.hpp:14226
T value
Definition: exprtk.hpp:6098
std::size_t position
Definition: exprtk.hpp:2182
static T evaluate(const Type x, const Type c4, const Type c3, const Type c2, const Type c1, const Type c0)
Definition: exprtk.hpp:35259
expression_node_ptr parse_special_function()
Definition: exprtk.hpp:23611
type_store & back()
Definition: exprtk.hpp:4202
vov_node(const T &var0, const T &var1)
Definition: exprtk.hpp:14355
details::expression_node< T > * expression_ptr
Definition: exprtk.hpp:16199
bool symbol_exists(const std::string &symbol_name) const
Definition: exprtk.hpp:16225
Definition: exprtk.hpp:4403
void restore_token()
Definition: exprtk.hpp:3986
Definition: exprtk.hpp:13226
std::size_t size
Definition: exprtk.hpp:4160
count< T > c
Definition: exprtk.hpp:38171
settings_logic_opr
Definition: exprtk.hpp:19280
Definition: exprtk.hpp:19264
const bool branch_deletable_
Definition: exprtk.hpp:7840
branch_t branch_[N]
Definition: exprtk.hpp:11308
bool is_right_bracket(const char_t c)
Definition: exprtk.hpp:137
T3 t3_
Definition: exprtk.hpp:13939
bool is_reserved_word(const std::string &symbol)
Definition: exprtk.hpp:500
static T process_1(const Sequence &arg_list)
Definition: exprtk.hpp:12525
std::size_t size() const
Definition: exprtk.hpp:8043
operator_type operation()
Definition: exprtk.hpp:5865
str_base_ptr str0_base_ptr_
Definition: exprtk.hpp:15069
T xnor_impl(const T v0, const T v1, real_type_tag)
Definition: exprtk.hpp:1160
covovov_t::type2 node_type
Definition: exprtk.hpp:32366
tmp_vs_t expr_as_vec1_store_
Definition: exprtk.hpp:11595
bool finished() const
Definition: exprtk.hpp:2294
bool enable_joiner_
Definition: exprtk.hpp:19790
T integrate(const expression< T > &e, T &x, const T &r0, const T &r1, const std::size_t number_of_intervals=1000000)
Definition: exprtk.hpp:34836
scoped_delete(parser< T > &pr, ptr_t(&p)[N])
Definition: exprtk.hpp:20721
static details::operator_type operation()
Definition: exprtk.hpp:12190
Definition: exprtk.hpp:35765
static T process(const std::string &t1, const std::string &t2)
Definition: exprtk.hpp:12188
static std::string id(expression_generator< Type > &expr_gen, const details::operator_type o0, const details::operator_type o1, const details::operator_type o2)
Definition: exprtk.hpp:32880
control_block()
Definition: exprtk.hpp:16656
PowOp operation_t
Definition: exprtk.hpp:15139
Definition: exprtk.hpp:4424
void set_expression(const expression_ptr expr)
Definition: exprtk.hpp:17817
range_interface< T > irange_t
Definition: exprtk.hpp:8744
virtual T value() const
Definition: exprtk.hpp:4944
igeneric_function< T > igeneric_function_t
Definition: exprtk.hpp:16203
bool collect_functions_enabled() const
Definition: exprtk.hpp:19433
sumk< T > sk
Definition: exprtk.hpp:38180
int insert(const lexer::token &t0, const lexer::token &t1, lexer::token &new_token)
Definition: exprtk.hpp:3186
std::pair< void *, std::size_t > void_t
Definition: exprtk.hpp:11423
bool is_letter_or_digit(const char_t c)
Definition: exprtk.hpp:127
static expression_node_ptr process(parser< Type > &p, const details::operator_type opt_type, const std::string &sf_name)
Definition: exprtk.hpp:23547
std::size_t size() const
Definition: exprtk.hpp:5262
variable_node< T > variable_node_t
Definition: exprtk.hpp:11415
bool add_replace(const std::string &target_symbol, const std::string &replace_symbol, const lexer::token::token_type token_type=lexer::token::e_symbol)
Definition: exprtk.hpp:3573
ivararg_function< T > ivararg_function_t
Definition: exprtk.hpp:16202
expression_node< T > * expression_ptr
Definition: exprtk.hpp:6044
type_store()
Definition: exprtk.hpp:4154
covovoc_t::sf4_type sf4_type
Definition: exprtk.hpp:31264
token_type type
Definition: exprtk.hpp:2180
const vds_t & vds() const
Definition: exprtk.hpp:10157
Definition: exprtk.hpp:15997
type_store_t & ts_
Definition: exprtk.hpp:4263
virtual ~string_base_node()
Definition: exprtk.hpp:5570
value_ptr data() const
Definition: exprtk.hpp:5418
virtual ~null_igenfunc()
Definition: exprtk.hpp:11787
details::stringvar_node< T > stringvar_node_t
Definition: exprtk.hpp:18153
static T process_5(const Sequence &arg_list)
Definition: exprtk.hpp:12354
vector_holder< T > vector_holder_t
Definition: exprtk.hpp:7075
Definition: exprtk.hpp:4406
T operator()(parameter_list_t parameters)
Definition: exprtk.hpp:36545
std::vector< branch_t > branch_
Definition: exprtk.hpp:11594
T g2d_impl(const T v, real_type_tag)
Definition: exprtk.hpp:1310
Definition: exprtk.hpp:12070
Definition: exprtk.hpp:4440
T(* bfunc_t)(Type t0, Type t1)
Definition: exprtk.hpp:2005
exprtk_define_erfc(float,::erfcf) exprtk_define_erfc(double
details::T0oT1oT2oT3< T, T0, T1, T2, T3, typename T0oT1oT20T3process< T >::mode4 > type4
Definition: exprtk.hpp:14342
expression_node_ptr parse_function_call(ifunction< T > *function, const std::string &function_name)
Definition: exprtk.hpp:20894
T0oT1oT2oT3_sf4ext< T, T0, T1, T2, T3, SF4Operation > node_type
Definition: exprtk.hpp:14228
Definition: exprtk.hpp:20813
Definition: exprtk.hpp:4429
expression_node_ptr synthesize_sos_expression(const details::operator_type &opr, expression_node_ptr(&branch)[2])
Definition: exprtk.hpp:33739
expression_node< T >::node_type type() const
Definition: exprtk.hpp:8967
virtual ~polynomial()
Definition: exprtk.hpp:35306
static std::string null_value
Definition: exprtk.hpp:7490
T d2r_impl(const T v, real_type_tag)
Definition: exprtk.hpp:1308
void clear_vectors()
Definition: exprtk.hpp:16757
#define exprtk_loop(N)
expression_node_ptr parse_vector()
Definition: exprtk.hpp:22945
vector_node< T > * vector_node_ptr
Definition: exprtk.hpp:7379
commutative_inserter()
Definition: exprtk.hpp:3177
sos_node< T, SType0, SType1, Operation > & operator=(sos_node< T, SType0, SType1, Operation > &)
std::pair< bool, expression_node_ptr > n1_e
Definition: exprtk.hpp:6943
Definition: exprtk.hpp:4921
dot()
Definition: exprtk.hpp:38084
T value() const
Definition: exprtk.hpp:9457
bool add_constants()
Definition: exprtk.hpp:17225
expression_node< T > * expression_ptr
Definition: exprtk.hpp:9755
Definition: exprtk.hpp:4429
static long double value()
Definition: exprtk.hpp:817
T value() const
Definition: exprtk.hpp:10073
bool is_integer(const T v)
Definition: exprtk.hpp:1524
static expression_node< T > * allocate(Allocator &allocator, T0 p0, T1 p1, T2 p2, bfunc_t p3, bfunc_t p4)
Definition: exprtk.hpp:13827
symbol_list_t assignment_name_list_
Definition: exprtk.hpp:19216
const T & v_
Definition: exprtk.hpp:15227
virtual expression_node< T > * branch(const std::size_t &index=0) const
Definition: exprtk.hpp:4949
static std::string data()
Definition: exprtk.hpp:38243
expression_node_ptr special_function(const details::operator_type &operation, expression_node_ptr(&branch)[4])
Definition: exprtk.hpp:27009
std::vector< std::string > retparam_list_t
Definition: exprtk.hpp:19162
std::pair< expression_ptr, bool > branch_t
Definition: exprtk.hpp:5840
igfun_t::parameter_list_t parameter_list_t
Definition: exprtk.hpp:37696
igfun_t::parameter_list_t parameter_list_t
Definition: exprtk.hpp:37639
#define register_sf3(Op)
parser_error::type get_error(const std::size_t &index)
Definition: exprtk.hpp:20151
functor_t::bfunc_t bfunc_t
Definition: exprtk.hpp:13464
repeat_until_loop_node(expression_ptr condition, expression_ptr loop_body)
Definition: exprtk.hpp:6222
exprtk::igeneric_function< T > igfun_t
Definition: exprtk.hpp:37526
token_t & operator[](const std::size_t &index)
Definition: exprtk.hpp:2278
virtual ~T0oT1oT2_base_node()
Definition: exprtk.hpp:13258
static T_ execute(ifunction &f, T_(&v)[20])
Definition: exprtk.hpp:11162
T value() const
Definition: exprtk.hpp:14460
covocov_t::sf4_type sf4_type
Definition: exprtk.hpp:33398
freefunc15(ff15_functor ff)
Definition: exprtk.hpp:16188
expression_node< T > * expression_ptr
Definition: exprtk.hpp:14832
operator_type operation() const
Definition: exprtk.hpp:14863
void enable_unknown_symbol_resolver(unknown_symbol_resolver &usr)
Definition: exprtk.hpp:20209
T nor_impl(const T v0, const T v1, int_type_tag)
Definition: exprtk.hpp:1142
functor_t::ufunc_t unary_functor_t
Definition: exprtk.hpp:9006
base_func(const std::size_t &pc=0)
Definition: exprtk.hpp:35504
expression_node_ptr const_optimise_switch(Sequence< expression_node_ptr, Allocator > &arg_list)
Definition: exprtk.hpp:26531
Definition: exprtk.hpp:4419
void start()
Definition: exprtk.hpp:36385
vocovov_t::type0 node_type
Definition: exprtk.hpp:30667
expression_node< T > * expression_ptr
Definition: exprtk.hpp:14351
bfunc_t f() const
Definition: exprtk.hpp:13731
Definition: exprtk.hpp:13170
Definition: exprtk.hpp:6164
vovovov_t::sf4_type sf4_type
Definition: exprtk.hpp:32143
~scoped_bool_or_restorer()
Definition: exprtk.hpp:20832
opr_base< T >::Type Type
Definition: exprtk.hpp:12122
static T process_1(const Sequence &arg_list)
Definition: exprtk.hpp:12261
vector_view< T > make_vector_view(T *data, const std::size_t size, const std::size_t offset=0)
Definition: exprtk.hpp:4128
Definition: exprtk.hpp:4410
expression_node< T >::node_type type() const
Definition: exprtk.hpp:7831
ff15_functor f
Definition: exprtk.hpp:16193
std::size_t depth
Definition: exprtk.hpp:18300
static expression_node_ptr process(expression_generator< Type > &expr_gen, const details::operator_type &operation, expression_node_ptr(&branch)[2])
Definition: exprtk.hpp:28571
static bool test(const PtrType, const void *)
Definition: exprtk.hpp:16419
Definition: exprtk.hpp:4432
igeneric_function< T >::parameter_list_t parameter_list_t
Definition: exprtk.hpp:36458
T value() const
Definition: exprtk.hpp:9958
void scan_operator()
Definition: exprtk.hpp:2496
func_5param()
Definition: exprtk.hpp:35797
Definition: exprtk.hpp:17554
static expression_node< T >::node_type type()
Definition: exprtk.hpp:11987
vector_holder< T > vector_holder_t
Definition: exprtk.hpp:7194
expression_node_ptr repeat_until_loop(expression_node_ptr &condition, expression_node_ptr &branch, const bool brkcont=false) const
Definition: exprtk.hpp:26438
vector_node_ptr vec() const
Definition: exprtk.hpp:10780
range_t rp_
Definition: exprtk.hpp:7561
static T_ execute(ifunction &f, T_(&v)[3])
Definition: exprtk.hpp:11281
T2 t2_
Definition: exprtk.hpp:13841
disabled_entity_set_t disabled_inequality_set_
Definition: exprtk.hpp:19808
ivararg_function< T > VAF
Definition: exprtk.hpp:18124
any_true< T > nt
Definition: exprtk.hpp:38169
func_6param()
Definition: exprtk.hpp:35811
covovov_t::type0 node_type
Definition: exprtk.hpp:30751
igfun_t::generic_type generic_type
Definition: exprtk.hpp:37007
expression_node_ptr varnode_optimise_sf3(const details::operator_type &operation, expression_node_ptr(&branch)[3])
Definition: exprtk.hpp:26872
Definition: exprtk.hpp:4393
static T process_5(const Sequence &arg_list)
Definition: exprtk.hpp:12708
void set_ref(data_ptr_t *data_ref)
Definition: exprtk.hpp:4115
vector_holder_t * vector_holder_ptr
Definition: exprtk.hpp:18238
static T process(Type t1, Type t2)
Definition: exprtk.hpp:12168
uchar_t const * uchar_cptr
Definition: exprtk.hpp:90
T atan2_impl(const T v0, const T v1, real_type_tag)
Definition: exprtk.hpp:1048
virtual ~cov_base_node()
Definition: exprtk.hpp:13116
VarArgFunction * function_
Definition: exprtk.hpp:11403
bool boc_optimisable(const details::operator_type &operation, expression_node_ptr(&branch)[2]) const
Definition: exprtk.hpp:25895
Definition: exprtk.hpp:19253
static const std::string arithmetic_ops_list[]
Definition: exprtk.hpp:476
std::string get_conststr_stringvar_name(const expression_node_ptr &ptr) const
Definition: exprtk.hpp:18935
std::deque< parser_error::type > error_list_
Definition: exprtk.hpp:34657
std::size_t scope_depth
Definition: exprtk.hpp:18993
~bipowninv_node()
Definition: exprtk.hpp:15244
bool is_reserved_symbol(const std::string &symbol)
Definition: exprtk.hpp:513
sort()
Definition: exprtk.hpp:37646
vector_view_t & vec_view_
Definition: exprtk.hpp:5384
#define base_opr_case(N)
details::functor_t< T > functor_t
Definition: exprtk.hpp:14047
T value() const
Definition: exprtk.hpp:6630
static T_ execute(ifunction &f, T_(&v)[6])
Definition: exprtk.hpp:11260
assignment_vec_elem_op_node(const operator_type &opr, expression_ptr branch0, expression_ptr branch1)
Definition: exprtk.hpp:9946
bool is_true(const double v)
Definition: exprtk.hpp:4963
unsigned char uchar_t
Definition: exprtk.hpp:86
Definition: exprtk.hpp:17565
Definition: exprtk.hpp:18313
operator_type operation() const
Definition: exprtk.hpp:15059
sf4_map_t * sf4_map_
Definition: exprtk.hpp:34367
std::vector< T > var_t
Definition: exprtk.hpp:35498
precedence_level
Definition: exprtk.hpp:18102
std::vector< lexer::token_inserter * > token_inserter_list
Definition: exprtk.hpp:3940
covovoc_t::type4 node_type
Definition: exprtk.hpp:33510
static void execute(T_(&v)[2], const branch_t(&b)[2])
Definition: exprtk.hpp:11140
T value() const
Definition: exprtk.hpp:10717
Definition: exprtk.hpp:5750
range_t & range_ref()
Definition: exprtk.hpp:8416
Definition: exprtk.hpp:4920
Definition: exprtk.hpp:5886
Definition: exprtk.hpp:18115
bool is_vararg_function(const std::string &vararg_function_name) const
Definition: exprtk.hpp:18887
str_base_ptr str1_base_ptr_
Definition: exprtk.hpp:8218
unknown_symbol_resolver default_usr_
Definition: exprtk.hpp:34663
binary_op_map_t * binary_op_map_
Definition: exprtk.hpp:34364
const range_t & range_ref() const
Definition: exprtk.hpp:8421
vocov_t::sf3_type sf3_type
Definition: exprtk.hpp:29658
Definition: exprtk.hpp:2025
void update(const T &v0, const T &v1, const T &v2)
Definition: exprtk.hpp:35525
details::scand_node< T > scand_node_t
Definition: exprtk.hpp:18170
Definition: exprtk.hpp:36593
Definition: exprtk.hpp:4455
T operator()(const std::size_t &ps_index, parameter_list_t parameters)
Definition: exprtk.hpp:38139
vector_holder_ptr get_vector(const std::string &vector_name) const
Definition: exprtk.hpp:16884
vocovov_t::type3 node_type
Definition: exprtk.hpp:32779
static expression_node_ptr process(expression_generator< Type > &expr_gen, const details::operator_type &operation, expression_node_ptr(&branch)[2])
Definition: exprtk.hpp:32898
bool run_assemblies()
Definition: exprtk.hpp:20060
Definition: exprtk.hpp:17969
T2 t2() const
Definition: exprtk.hpp:13801
details::assignment_vec_elem_node< T > assignment_vec_elem_node_t
Definition: exprtk.hpp:18165
static T process(Type t1, Type t2)
Definition: exprtk.hpp:12141
str_base_ptr str0_base_ptr_
Definition: exprtk.hpp:8841
void set(const precedence_level &l, const precedence_level &r, const details::operator_type &o)
Definition: exprtk.hpp:20388
void clear_errors()
Definition: exprtk.hpp:3697
T log_impl(const T v, real_type_tag)
Definition: exprtk.hpp:1294
vector_holder_t * vector_holder_ptr
Definition: exprtk.hpp:7076
lvr_vec_t lv
Definition: exprtk.hpp:35700
vector_node_ptr vec()
Definition: exprtk.hpp:7032
sf4_map_t sf4_map_
Definition: exprtk.hpp:34669
T value() const
Definition: exprtk.hpp:9921
generic_string_range_node(expression_ptr str_branch, const range_t &brange)
Definition: exprtk.hpp:7734
Definition: exprtk.hpp:16023
expression_node< typename ResultNode::value_type > * allocate(OpType &operation, ExprNode(&branch)[1])
Definition: exprtk.hpp:15411
expression_ptr condition_
Definition: exprtk.hpp:6262
static std::string id(expression_generator< Type > &expr_gen, const details::operator_type o0, const details::operator_type o1, const details::operator_type o2)
Definition: exprtk.hpp:31629
static T process(const arg_list_t &arg)
Definition: exprtk.hpp:26641
static details::operator_type operation()
Definition: exprtk.hpp:12134
axpbyz< T > b1_axpbyz
Definition: exprtk.hpp:38184
T shr_impl(const T v0, const T v1, int_type_tag)
Definition: exprtk.hpp:1066
void activate_side_effect(const std::string &)
Definition: exprtk.hpp:18975
exprtk::igeneric_function< T > igfun_t
Definition: exprtk.hpp:37737
igfun_t::parameter_list_t parameter_list_t
Definition: exprtk.hpp:37582
T value_type
Definition: exprtk.hpp:13952
T modulus_impl(const T v0, const T v1, real_type_tag)
Definition: exprtk.hpp:929
range_interface< T > irange_t
Definition: exprtk.hpp:8585
expression_node< T > * branch(const std::size_t &index=0) const
Definition: exprtk.hpp:5818
precedence_level left
Definition: exprtk.hpp:20404
const value_t * begin() const
Definition: exprtk.hpp:4250
Definition: exprtk.hpp:17978
virtual bool side_effect() const
Definition: exprtk.hpp:6996
std::size_t current_index_
Definition: exprtk.hpp:3549
cob_node< T, Operation > & operator=(const cob_node< T, Operation > &)
static T process_1(const Sequence &arg_list)
Definition: exprtk.hpp:12754
bool wc_match(const std::string &wild_card, const std::string &str)
Definition: exprtk.hpp:632
static std::string id(expression_generator< Type > &expr_gen, const details::operator_type o0, const details::operator_type o1, const details::operator_type o2)
Definition: exprtk.hpp:31737
bool add_variable(const std::string &variable_name, T &t, const bool is_constant=false)
Definition: exprtk.hpp:16974
Type * ptr_t
Definition: exprtk.hpp:20750
virtual const T & v0() const =0
value_t * begin()
Definition: exprtk.hpp:4251
Definition: exprtk.hpp:14765
expression_node_ptr parse_for_loop()
Definition: exprtk.hpp:21788
expression_node< T > * expression_ptr
Definition: exprtk.hpp:7855
static T process(Type t1, Type t2)
Definition: exprtk.hpp:12083
expression_node_ptr vararg_function_call(ivararg_function_t *vaf, std::vector< expression_node_ptr > &arg_list)
Definition: exprtk.hpp:27223
bool operator!() const
Definition: exprtk.hpp:17737
std::pair< expression_ptr, bool > branch_t
Definition: exprtk.hpp:14658
virtual std::size_t size() const =0
Definition: exprtk.hpp:4150
Definition: exprtk.hpp:4438
vocovoc_t::sf4_type sf4_type
Definition: exprtk.hpp:31025
range_t & range_ref()
Definition: exprtk.hpp:8048
Definition: exprtk.hpp:4394
operator_type operation() const
Definition: exprtk.hpp:13968
array_vector_impl operator=(const array_vector_impl &)
static T process(const arg_list_t &arg)
Definition: exprtk.hpp:26610
T value() const
Definition: exprtk.hpp:6242
operator_type operation() const
Definition: exprtk.hpp:14243
range_pack< T > range_t
Definition: exprtk.hpp:11735
Definition: exprtk.hpp:35150
expression_node< T > * expression_ptr
Definition: exprtk.hpp:6109
virtual T operator()(parameter_list_t) igeneric_function_empty_body(1) inline virtual T operator()(std return_type rtrn_type
Definition: exprtk.hpp:15977
Definition: exprtk.hpp:4448
void * data
Definition: exprtk.hpp:6967
T r2d_impl(const T v, real_type_tag)
Definition: exprtk.hpp:1307
const symbol_table< T > & get_symbol_table(const std::size_t &index=0) const
Definition: exprtk.hpp:17782
bool branch_deletable_
Definition: exprtk.hpp:13440
static T process(const ivector_ptr v)
Definition: exprtk.hpp:13037
bool add_reserved_function(const std::string &vararg_function_name, vararg_function_t &vararg_function)
Definition: exprtk.hpp:17097
Definition: exprtk.hpp:4408
Definition: exprtk.hpp:4437
virtual const T c() const =0
~control_block()
Definition: exprtk.hpp:4574
static expression_node_ptr process(expression_generator< Type > &expr_gen, const details::operator_type &operation, expression_node_ptr(&branch)[2])
Definition: exprtk.hpp:30842
std::list< T > local_symbol_list_
Definition: exprtk.hpp:16650
token_t & next_token()
Definition: exprtk.hpp:2258
lexer::helper::sequence_validator sequence_validator_
Definition: exprtk.hpp:34681
T operator()(const std::size_t &ps_index, parameter_list_t parameters)
Definition: exprtk.hpp:36828
ProcessMode process_mode_t
Definition: exprtk.hpp:13859
bool is_constant_foldable(NodePtr(&b)[N]) const
Definition: exprtk.hpp:27482
const T & ref() const
Definition: exprtk.hpp:7216
static T execute(ifunction &, branch_t(&)[ParamCount])
Definition: exprtk.hpp:11157
T value_t
Definition: exprtk.hpp:4273
Definition: exprtk.hpp:4415
covovov_t::sf4_type sf4_type
Definition: exprtk.hpp:32836
T value() const
Definition: exprtk.hpp:9655
expression_node< typename ResultNode::value_type > * allocate(OpType &operation, ExprNode(&branch)[3])
Definition: exprtk.hpp:15423
Definition: exprtk.hpp:12156
T1 t1() const
Definition: exprtk.hpp:13983
static expression_node_ptr process(expression_generator< Type > &expr_gen, const details::operator_type &operation, expression_node_ptr(&branch)[2])
Definition: exprtk.hpp:30138
bool is_constant(const std::string &symbol_name) const
Definition: exprtk.hpp:16256
trinary_node(const operator_type &opr, expression_ptr branch0, expression_ptr branch1, expression_ptr branch2)
Definition: exprtk.hpp:5893
Definition: exprtk.hpp:4408
Definition: exprtk.hpp:4400
Definition: exprtk.hpp:4423
void populate_value_list() const
Definition: exprtk.hpp:11395
details::T0oT1oT2_define< T, const_t, cref_t, const_t > covoc_t
Definition: exprtk.hpp:18206
Definition: exprtk.hpp:4453
lexer::token_inserter * error_token_inserter
Definition: exprtk.hpp:3945
opr_base< T >::Type Type
Definition: exprtk.hpp:12421
void register_local_var(vector_holder_ptr vec_holder)
Definition: exprtk.hpp:17848
expression_node< T >::node_type type() const
Definition: exprtk.hpp:11834
Definition: exprtk.hpp:5564
std::string type_id() const
Definition: exprtk.hpp:14190
#define def_fp_retval(N)
Definition: exprtk.hpp:35840
vovocov_t::sf4_type sf4_type
Definition: exprtk.hpp:30584
details::node_allocator * node_allocator_
Definition: exprtk.hpp:34361
Definition: exprtk.hpp:4910
assignment_vecvec_node(const operator_type &opr, expression_ptr branch0, expression_ptr branch1)
Definition: exprtk.hpp:9759
Definition: exprtk.hpp:2019
T operator()(const std::size_t &ps_index, parameter_list_t parameters)
Definition: exprtk.hpp:38046
SType1 s1_
Definition: exprtk.hpp:14818
data_ptr_t data() const
Definition: exprtk.hpp:4095
bool replace_symbol(const std::string &old_symbol, const std::string &new_symbol)
Definition: exprtk.hpp:20179
Definition: exprtk.hpp:4910
copy()
Definition: exprtk.hpp:37388
str_base_ptr str1_base_ptr_
Definition: exprtk.hpp:8568
expression_ptr loop_body_
Definition: exprtk.hpp:6412
Definition: exprtk.hpp:36813
details::sf3ext_type_node< T, T0, T1, T2 > sf3_type_node
Definition: exprtk.hpp:14332
expression_node< T >::node_type type() const
Definition: exprtk.hpp:7221
bool string_to_type_converter_impl_ref(Iterator &itr, const Iterator end, T &result)
Definition: exprtk.hpp:1680
static bool cmp(const char_t c0, const char_t c1)
Definition: exprtk.hpp:575
bool branch_deletable(expression_node< T > *node)
Definition: exprtk.hpp:5136
Definition: exprtk.hpp:4393
Definition: exprtk.hpp:18116
expression_node< typename node_type::value_type > * allocate(const Sequence< Type, Allocator > &seq) const
Definition: exprtk.hpp:15456
T0oT1oT2oT3_sf4(node_type &)
Definition: exprtk.hpp:14210
T3 t3() const
Definition: exprtk.hpp:14180
bool add_reserved_function(const std::string &function_name, generic_function_t &function)
Definition: exprtk.hpp:17109
parser_t & parser_
Definition: exprtk.hpp:23317
Definition: exprtk.hpp:4445
static void print(const string_t &s)
Definition: exprtk.hpp:36502
bool peek_token_is(const token_t::token_type &ttype)
Definition: exprtk.hpp:4045
T sinh_impl(const T v, real_type_tag)
Definition: exprtk.hpp:1300
string_size_node(expression_ptr brnch)
Definition: exprtk.hpp:8265
expression_node< T > * branch(const std::size_t &) const
Definition: exprtk.hpp:14527
virtual std::string type_id() const =0
settings_store & enable_inequality_operation(settings_inequality_opr inequality)
Definition: exprtk.hpp:19709
Definition: exprtk.hpp:4908
expression_node< T >::node_type type() const
Definition: exprtk.hpp:8833
static std::string id(expression_generator< Type > &expr_gen, const details::operator_type o0, const details::operator_type o1, const details::operator_type o2)
Definition: exprtk.hpp:32187
expression_node< typename ResultNode::value_type > * allocate(OpType &operation, ExprNode(&branch)[5])
Definition: exprtk.hpp:15435
Definition: exprtk.hpp:15933
vector_node< T > * vector_node_ptr
Definition: exprtk.hpp:9639
const T c() const
Definition: exprtk.hpp:14622
dependent_entity_collector dec_
Definition: exprtk.hpp:34656
details::T0oT1oT2_define< T, const_t, const_t, cref_t > cocov_t
Definition: exprtk.hpp:18207
Definition: exprtk.hpp:12080
operator_type operation() const
Definition: exprtk.hpp:13419
details::functor_t< T > functor_t
Definition: exprtk.hpp:14136
vector_node_ptr vec()
Definition: exprtk.hpp:10630
Definition: exprtk.hpp:16000
generic_type::vector_view vector_t
Definition: exprtk.hpp:38080
void set_error(const parser_error::type &error_type)
Definition: exprtk.hpp:34371
vector_node_ptr vec1_node_ptr_
Definition: exprtk.hpp:10501
static void execute(T_(&v)[5], const branch_t(&b)[5])
Definition: exprtk.hpp:11104
void add_invalid(lexer::token::token_type base, lexer::token::token_type t)
Definition: exprtk.hpp:3704
range_t & range_ref()
Definition: exprtk.hpp:5628
file_descriptor(const std::string &fname, const std::string &access)
Definition: exprtk.hpp:36601
control_block & operator=(const control_block &)
expression_node< T > * expression_ptr
Definition: exprtk.hpp:10056
bool original_value_
Definition: exprtk.hpp:20838
const ufunc_t u0_
Definition: exprtk.hpp:13383
bool is_string_range_node(const expression_node< T > *node)
Definition: exprtk.hpp:15322
Definition: exprtk.hpp:13639
expression_ptr consequent_
Definition: exprtk.hpp:8729
T value() const
Definition: exprtk.hpp:5444
type_map_t::const_iterator tm_const_itr_t
Definition: exprtk.hpp:16214
swap_genstrings_node< T > & operator=(swap_genstrings_node< T > &)
~vec_binop_vecval_node()
Definition: exprtk.hpp:10556
bool operator()(const lexer::token &t0, const lexer::token &t1)
Definition: exprtk.hpp:3663
exprtk::igeneric_function< T > igfun_t
Definition: exprtk.hpp:37289
Definition: exprtk.hpp:15996
std::vector< unsigned char > delete_branch_
Definition: exprtk.hpp:6760
T value() const
Definition: exprtk.hpp:10218
assignment_node(const operator_type &opr, expression_ptr branch0, expression_ptr branch1)
Definition: exprtk.hpp:9487
generic_type::scalar_view scalar_t
Definition: exprtk.hpp:37107
static T process_5(const Sequence &arg_list)
Definition: exprtk.hpp:12287
static expression_node_ptr process(expression_generator< Type > &expr_gen, const details::operator_type &operation, expression_node_ptr(&branch)[2])
Definition: exprtk.hpp:32543
generic_type::vector_view vector_t
Definition: exprtk.hpp:36953
void clear()
Definition: exprtk.hpp:4366
bool is_constant_foldable(const Sequence< NodePtr, Allocator > &b) const
Definition: exprtk.hpp:27498
static details::operator_type operation()
Definition: exprtk.hpp:11988
bool is_cob_node(const expression_node< T > *node)
Definition: exprtk.hpp:15286
swap_string_node(expression_ptr branch0, expression_ptr branch1)
Definition: exprtk.hpp:8001
char_t * char_ptr
Definition: exprtk.hpp:89
T1 t1() const
Definition: exprtk.hpp:14170
Definition: exprtk.hpp:4410
expression_node_ptr synthesize_uv_expression(const details::operator_type &operation, expression_node_ptr(&branch)[1])
Definition: exprtk.hpp:26788
std::size_t assignment_symbols(Sequence< symbol_t, Allocator > &assignment_list)
Definition: exprtk.hpp:19107
expression_node< T > * expression_ptr
Definition: exprtk.hpp:8857
details::expression_node< T > * expression_ptr
Definition: exprtk.hpp:16581
const range_t & range_ref() const
Definition: exprtk.hpp:8554
lexer::token token_t
Definition: exprtk.hpp:18172
Definition: exprtk.hpp:4914
T0oT1oT2_sf3ext(node_type &)
Definition: exprtk.hpp:14109
expression_node< T > * expression_ptr
Definition: exprtk.hpp:10179
range_t rp_
Definition: exprtk.hpp:7716
opr_base< T >::Type Type
Definition: exprtk.hpp:12492
static expression_node< T > * allocate(Allocator &allocator, T0 p0, T1 p1, T2 p2)
Definition: exprtk.hpp:14100
freefunc02(ff02_functor ff)
Definition: exprtk.hpp:16047
void parse_pending_string_rangesize(expression_node_ptr &expression)
Definition: exprtk.hpp:22418
Definition: exprtk.hpp:19066
covocov_t::type3 node_type
Definition: exprtk.hpp:32891
function_traits()
Definition: exprtk.hpp:15758
control_block(const std::size_t &dsize)
Definition: exprtk.hpp:4560
expression_node< T > * expression_ptr
Definition: exprtk.hpp:10330
virtual const T c() const =0
opr_base< T >::Type Type
Definition: exprtk.hpp:12298
token_inserter(const std::size_t &stride)
Definition: exprtk.hpp:2992
std::map< std::string, std::pair< trinary_functor_t,operator_t > > sf3_map_t
Definition: exprtk.hpp:18191
void clear_local_constants()
Definition: exprtk.hpp:16762
str_base_ptr str1_base_ptr_
Definition: exprtk.hpp:7979
virtual operator_type operation() const
Definition: exprtk.hpp:13233
expression_node< T >::node_type type() const
Definition: exprtk.hpp:11388
bool is_base_function(const std::string &function_name)
Definition: exprtk.hpp:526
static expression_node< T >::node_type type()
Definition: exprtk.hpp:12105
T erfc_impl(T v, int_type_tag)
Definition: exprtk.hpp:1248
Definition: exprtk.hpp:17973
Definition: exprtk.hpp:37331
const unsigned int global_loop_batch_size
Definition: exprtk.hpp:4505
T0_ T0
Definition: exprtk.hpp:13854
range_t * range_ptr
Definition: exprtk.hpp:7997
expression_node_ptr parse_null_statement()
Definition: exprtk.hpp:23656
results_context_t * results_context_
Definition: exprtk.hpp:11895
#define exprtk_disable_fallthrough_begin
Definition: exprtk.hpp:80
void set_bom(binary_op_map_t &binary_op_map)
Definition: exprtk.hpp:25529
expression_ptr branch_
Definition: exprtk.hpp:5700
T2 t2_
Definition: exprtk.hpp:13938
Definition: exprtk.hpp:13484
assignment_string_range_node(const operator_type &opr, expression_ptr branch0, expression_ptr branch1)
Definition: exprtk.hpp:8455
vec_data_store(const type &vds)
Definition: exprtk.hpp:4646
unary_op_map_t unary_op_map_
Definition: exprtk.hpp:34665
std::size_t size()
Definition: exprtk.hpp:4688
T value() const
Definition: exprtk.hpp:8020
Definition: exprtk.hpp:35793
details::T0oT1_define< T, const_t, cref_t > cov_t
Definition: exprtk.hpp:18199
expression_node< T > * expression_ptr
Definition: exprtk.hpp:6273
expression_node_ptr parse_while_loop()
Definition: exprtk.hpp:21550
expression_node_ptr parse_vararg_function_call(ivararg_function< T > *vararg_function, const std::string &vararg_function_name)
Definition: exprtk.hpp:23032
static bool is_variable(const expression< T > &expr)
Definition: exprtk.hpp:17933
Definition: exprtk.hpp:4440
generic_function_node< T, igeneric_function_t > gen_function_t
Definition: exprtk.hpp:11807
std::size_t ref_count
Definition: exprtk.hpp:17675
disabled_entity_set_t disabled_logic_set_
Definition: exprtk.hpp:19805
symbol_table_t::local_data_t local_data_t
Definition: exprtk.hpp:18549
expression_node_ptr synthesize_csocsr_expression(const details::operator_type &opr, expression_node_ptr(&branch)[2])
Definition: exprtk.hpp:33897
static std::string id()
Definition: exprtk.hpp:13493
vector_node_ptr vec() const
Definition: exprtk.hpp:10132
Definition: exprtk.hpp:14542
vec_binop_vecval_node(const operator_type &opr, expression_ptr branch0, expression_ptr branch1)
Definition: exprtk.hpp:10519
Sequence< Type, Allocator > sequence_t
Definition: exprtk.hpp:5323
static expression_node< T >::node_type type()
Definition: exprtk.hpp:12095
Definition: exprtk.hpp:6976
Definition: exprtk.hpp:13445
bool init_branches(expression_ptr(&b)[NumBranches])
Definition: exprtk.hpp:11039
function_t & setup(expression_t &expr)
Definition: exprtk.hpp:35551
std::pair< expression_ptr, bool > branch_t
Definition: exprtk.hpp:14497
details::expression_node< Type > * expression_node_ptr
Definition: exprtk.hpp:25439
irange_ptr str1_range_ptr_
Definition: exprtk.hpp:7981
exprtk::igeneric_function< T > igfun_t
Definition: exprtk.hpp:37581
vds_t & vds()
Definition: exprtk.hpp:10800
Definition: exprtk.hpp:2021
void set_min_num_args(FunctionType &func, const std::size_t &num_args)
Definition: exprtk.hpp:15823
unary_branch_node(expression_ptr brnch)
Definition: exprtk.hpp:13396
#define exprtk_define_unary_function(FunctionName)
Definition: exprtk.hpp:1566
Definition: exprtk.hpp:5581
T value_type
Definition: exprtk.hpp:4938
expression_node< typename node_type::value_type > * allocate_tt(T1 t1, T2 t2) const
Definition: exprtk.hpp:15503
value_ptr value_at(const std::size_t &index) const
Definition: exprtk.hpp:5370
expression_node_ptr const_optimise_varargfunc(const details::operator_type &operation, Sequence< expression_node_ptr, Allocator > &arg_list)
Definition: exprtk.hpp:27044
Definition: exprtk.hpp:14397
lexer::token token
Definition: exprtk.hpp:17986
Definition: exprtk.hpp:36511
Definition: exprtk.hpp:18106
irange_ptr str1_range_ptr_
Definition: exprtk.hpp:8724
expression_node_ptr special_function(const details::operator_type &operation, expression_node_ptr(&branch)[3])
Definition: exprtk.hpp:26904
Definition: exprtk.hpp:16093
switch_n_node(const Sequence< expression_ptr, Allocator > &arg_list)
Definition: exprtk.hpp:6673
Definition: exprtk.hpp:4412
T value() const
Definition: exprtk.hpp:9499
std::size_t parse_base_function_call(expression_node_ptr(&param_list)[MaxNumberofParameters], const std::string &function_name="")
Definition: exprtk.hpp:21009
token_joiner(const std::size_t &stride)
Definition: exprtk.hpp:3078
T frac_impl(const T v, real_type_tag)
Definition: exprtk.hpp:1312
Definition: exprtk.hpp:4450
T or_impl(const T v0, const T v1, real_type_tag)
Definition: exprtk.hpp:1124
static T process(Type t1, Type t2)
Definition: exprtk.hpp:12020
expression_node< typename node_type::value_type > * allocate_type(T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7) const
Definition: exprtk.hpp:15676
static expression_node_ptr process(expression_generator< Type > &, const details::operator_type &, expression_node_ptr(&)[2])
Definition: exprtk.hpp:30126
std::size_t size() const
Definition: exprtk.hpp:10296
vector_node_ptr vec() const
Definition: exprtk.hpp:10625
range_list_t range_list_
Definition: exprtk.hpp:11596
details::functor_t< T > functor_t
Definition: exprtk.hpp:13851
vds_t & vds()
Definition: exprtk.hpp:10152
exprtk::igeneric_function< T > igfun_t
Definition: exprtk.hpp:37335
axpy()
Definition: exprtk.hpp:37840
static expression_node< T >::node_type type()
Definition: exprtk.hpp:12023
Definition: exprtk.hpp:4453
details::T0oT1oT2oT3< T, T0, T1, T2, T3, typename T0oT1oT20T3process< T >::mode3 > type3
Definition: exprtk.hpp:14341
static T_ execute(ifunction &f, T_(&v)[13])
Definition: exprtk.hpp:11211
covov_t::sf3_type sf3_type
Definition: exprtk.hpp:29838
T value() const
Definition: exprtk.hpp:14512
expression_node_ptr parse_base_operation()
Definition: exprtk.hpp:21081
~break_node()
Definition: exprtk.hpp:6116
functor_t::ufunc_t ufunc_t
Definition: exprtk.hpp:13325
vds_t vds_
Definition: exprtk.hpp:10170
static T process(Type t1, Type t2)
Definition: exprtk.hpp:12132
RawType & type_ref(const std::string &symbol_name)
Definition: exprtk.hpp:16484
igfun_t::generic_type generic_type
Definition: exprtk.hpp:36893
Definition: exprtk.hpp:4442
igfun_t::generic_type generic_type
Definition: exprtk.hpp:37528
value_t & operator()()
Definition: exprtk.hpp:4283
Definition: exprtk.hpp:13946
sf3_map_t sf3_map_
Definition: exprtk.hpp:34668
functor_t::bfunc_t bfunc_t
Definition: exprtk.hpp:13324
T min(const T v0, const T v1)
Definition: exprtk.hpp:1391
T value() const
Definition: exprtk.hpp:14562
vector_node_ptr vec()
Definition: exprtk.hpp:10286
virtual ~boc_base_node()
Definition: exprtk.hpp:13194
range_pack< T > range_t
Definition: exprtk.hpp:8583
bool add_function(const std::string &vararg_function_name, vararg_function_t &vararg_function)
Definition: exprtk.hpp:17027
expression_node_ptr synthesize_str_xoxr_expression_impl(const details::operator_type &opr, T0 s0, T1 s1, range_t rp1)
Definition: exprtk.hpp:33689
bool operator<(const value_t lhs, const value_t rhs) noexcept
comparison operator for JSON types
Definition: json.h:429
bool add(const std::string &symbol_name, std::deque< T, Allocator > &v, const bool is_const=false)
Definition: exprtk.hpp:16357
expression_node< typename ResultNode::value_type > * allocate(OpType &operation, ExprNode(&branch)[4])
Definition: exprtk.hpp:15429
Definition: exprtk.hpp:12363
vocovoc_t::sf4_type sf4_type
Definition: exprtk.hpp:33454
bool add(const std::string &symbol_name, T(&v)[v_size], const bool is_const=false)
Definition: exprtk.hpp:16331
virtual operator_type operation() const
Definition: exprtk.hpp:13101
expression_node< T > * expression_ptr
Definition: exprtk.hpp:6220
vector_holder(std::vector< Type, Allocator > &vec)
Definition: exprtk.hpp:5400
static std::string id(expression_generator< Type > &expr_gen, const details::operator_type o0, const details::operator_type o1)
Definition: exprtk.hpp:29889
sf3_map_t * sf3_map_
Definition: exprtk.hpp:34366
static st_data * create()
Definition: exprtk.hpp:16639
axpbz()
Definition: exprtk.hpp:38036
variable_t * variable_ptr
Definition: exprtk.hpp:16584
vovovoc_t::sf4_type sf4_type
Definition: exprtk.hpp:32199
expression_node_ptr vectorize_func(const details::operator_type &operation, Sequence< expression_node_ptr, Allocator > &arg_list)
Definition: exprtk.hpp:27111
Definition: exprtk.hpp:4413
virtual operator_type operation() const
Definition: exprtk.hpp:13247
Definition: exprtk.hpp:4416
const bool condition_deletable_
Definition: exprtk.hpp:6264
const range_t & range_ref() const
Definition: exprtk.hpp:5633
vovocov_t::type0 node_type
Definition: exprtk.hpp:30583
std::vector< std::pair< lexer::token, lexer::token > > error_list_
Definition: exprtk.hpp:3788
nthelement< T > ne
Definition: exprtk.hpp:38178
igfun_t::parameter_list_t parameter_list_t
Definition: exprtk.hpp:37290
Definition: exprtk.hpp:17975
error_mode mode
Definition: exprtk.hpp:17987
static expression_node_ptr process(expression_generator< Type > &expr_gen, const details::operator_type &operation, expression_node_ptr(&branch)[2])
Definition: exprtk.hpp:28689
static T process(const Sequence< Type, Allocator > &arg_list)
Definition: exprtk.hpp:12568
static expression_node_ptr process(expression_generator< Type > &expr_gen, const details::operator_type &operation, expression_node_ptr(&branch)[2])
Definition: exprtk.hpp:33124
bool is_stringvar(const std::string &stringvar_name) const
Definition: exprtk.hpp:17343
exprtk::symbol_table< T > symbol_table_t
Definition: exprtk.hpp:35396
expression_node< T > * expression_ptr
Definition: exprtk.hpp:7132
Definition: exprtk.hpp:4403
Definition: exprtk.hpp:4921
cob_node(const T const_var, const expression_ptr brnch)
Definition: exprtk.hpp:14601
bool src_is_ivec_
Definition: exprtk.hpp:9898
long long int to_int64(const T v)
Definition: exprtk.hpp:1377
int vn
Definition: obj.cpp:20
bool is_constant_string(const std::string &symbol_name) const
Definition: exprtk.hpp:16929
virtual void set_c(const T)=0
bool allow_zero_parameters() const
Definition: exprtk.hpp:23221
Definition: exprtk.hpp:4435
std::size_t size
Definition: exprtk.hpp:17593
T value() const
Definition: exprtk.hpp:11328
Definition: exprtk.hpp:4450
details::literal_node< T > literal_node_t
Definition: exprtk.hpp:18130
Definition: exprtk.hpp:13592
vector_node_ptr vec() const
Definition: exprtk.hpp:7441
symbol_table_t & get_symbol_table(const std::size_t &index=0)
Definition: exprtk.hpp:18951
type_map_t map
Definition: exprtk.hpp:16218
expression_node< T > * expression_ptr
Definition: exprtk.hpp:11316
~const_string_range_node()
Definition: exprtk.hpp:7666
Operation operation_t
Definition: exprtk.hpp:14659
Definition: exprtk.hpp:12419
exprtk_define_freefunction(00) exprtk_define_freefunction(01) exprtk_define_freefunction(02) exprtk_define_freefunction(03) exprtk_define_freefunction(04) exprtk_define_freefunction(05) exprtk_define_freefunction(06) exprtk_define_freefunction(07) exprtk_define_freefunction(08) exprtk_define_freefunction(09) exprtk_define_freefunction(10) exprtk_define_freefunction(11) exprtk_define_freefunction(12) exprtk_define_freefunction(13) exprtk_define_freefunction(14) exprtk_define_freefunction(15) inline bool add_reserved_function(const std
Definition: exprtk.hpp:17074
virtual void reset()
Definition: exprtk.hpp:2856
details::vector_holder< T > vector_t
Definition: exprtk.hpp:16204
opr_base< T >::Type Type
Definition: exprtk.hpp:12643
Definition: exprtk.hpp:4459
static T process(const arg_list_t &arg)
Definition: exprtk.hpp:26620
Definition: exprtk.hpp:4398
T equal(const T v0, const T v1)
Definition: exprtk.hpp:1405
static std::string id(expression_generator< Type > &expr_gen, const details::operator_type o0, const details::operator_type o1)
Definition: exprtk.hpp:29527
vec_data_store< T > vds_t
Definition: exprtk.hpp:10181
opr_base< T >::Type Type
Definition: exprtk.hpp:12072
expression_node< T > * expression_ptr
Definition: exprtk.hpp:9388
vocovov_t::type1 node_type
Definition: exprtk.hpp:31804
vector_node_ptr temp_vec_node_
Definition: exprtk.hpp:10966
static void execute(Sequence< std::pair< expression_node< T > *, bool >, Allocator > &branch)
Definition: exprtk.hpp:5767
expression_node< T > * expression_node_ptr
Definition: exprtk.hpp:6827
exprtk::igeneric_function< T > igfun_t
Definition: exprtk.hpp:37197
type_store & operator[](const std::size_t &index)
Definition: exprtk.hpp:4182
Definition: exprtk.hpp:4436
Definition: exprtk.hpp:4458
bool in_use_
Definition: exprtk.hpp:36427
settings_store & enable_all_base_functions()
Definition: exprtk.hpp:19323
igeneric_function< T >::parameter_list_t parameter_list_t
Definition: exprtk.hpp:36535
T value() const
Definition: exprtk.hpp:5852
static expression_node_ptr process(expression_generator< Type > &, const details::operator_type &, expression_node_ptr(&)[2])
Definition: exprtk.hpp:32594
Definition: exprtk.hpp:14447
conditional_node(expression_ptr test, expression_ptr consequent, expression_ptr alternative)
Definition: exprtk.hpp:5986
const bool condition_deletable_
Definition: exprtk.hpp:6211
Definition: exprtk.hpp:4393
vds_t & vds()
Definition: exprtk.hpp:10952
T ceil_impl(const T v, real_type_tag)
Definition: exprtk.hpp:1289
generic_type::vector_view vector_t
Definition: exprtk.hpp:37741
const vds_t & vds() const
Definition: exprtk.hpp:9738
unary_variable_node(const T &var)
Definition: exprtk.hpp:13283
#define parse_digit_1(d)
value_ptr operator[](const std::size_t &index) const
Definition: exprtk.hpp:5408
replace_map_t replace_map_
Definition: exprtk.hpp:3617
Operation operation_t
Definition: exprtk.hpp:14770
vector_node_ptr vec0_node_ptr_
Definition: exprtk.hpp:10964
virtual operator_type operation() const
Definition: exprtk.hpp:13197
T value() const
Definition: exprtk.hpp:9268
bool register_inserter(lexer::token_inserter *inserter)
Definition: exprtk.hpp:3835
T log2_impl(const T v, real_type_tag)
Definition: exprtk.hpp:1296
std::size_t size() const
Definition: exprtk.hpp:7816
any_false()
Definition: exprtk.hpp:37296
details::functor_t< T > functor_t
Definition: exprtk.hpp:13950
virtual const T c() const =0
Definition: exprtk.hpp:10051
details::trinary_node< T > trinary_node_t
Definition: exprtk.hpp:18133
bool all_nodes_valid(expression_node< T > *(&b)[N])
Definition: exprtk.hpp:5143
static std::string id(expression_generator< Type > &expr_gen, const details::operator_type o0, const details::operator_type o1, const details::operator_type o2)
Definition: exprtk.hpp:32525
vector_holder_ptr get_vector(const std::string &vector_name) const
Definition: exprtk.hpp:18745
bool is_invalid_assignment_operation(const details::operator_type operation)
Definition: exprtk.hpp:20268
results_context_t * results_context_
Definition: exprtk.hpp:11841
static expression_node_ptr process(expression_generator< Type > &expr_gen, const details::operator_type &operation, expression_node_ptr(&branch)[2])
Definition: exprtk.hpp:32205
SType0 s0_
Definition: exprtk.hpp:14880
std::string type_id() const
Definition: exprtk.hpp:14273
voc_node(const T &var, const T &const_var)
Definition: exprtk.hpp:14455
const e_voc T1 e_none const e_none T1 e_none T0
Definition: exprtk.hpp:13638
std::size_t get_list(Sequence< std::pair< std::string, RawType >, Allocator > &list) const
Definition: exprtk.hpp:16538
static expression_node_ptr process(expression_generator< Type > &expr_gen, const details::operator_type &operation, expression_node_ptr(&branch)[2])
Definition: exprtk.hpp:31031
Definition: exprtk.hpp:4432
vector_node_ptr vec() const
Definition: exprtk.hpp:7027
std::vector< unsigned char > delete_branch_
Definition: exprtk.hpp:8980
Definition: exprtk.hpp:4910
#define vector_ops
bool parsing_break_stmt
Definition: exprtk.hpp:18989
static T process(const Sequence< Type, Allocator > &arg_list)
Definition: exprtk.hpp:12370
T operator()(const std::size_t &ps_index, parameter_list_t parameters)
Definition: exprtk.hpp:37945
expression_ptr test_
Definition: exprtk.hpp:8728
expression_node< T >::node_type type() const
Definition: exprtk.hpp:15054
details::T0oT1oT2oT3< T, T0, T1, T2, T3, typename T0oT1oT20T3process< T >::mode0 > type0
Definition: exprtk.hpp:14338
bool add_epsilon()
Definition: exprtk.hpp:17239
expression_node_ptr synthesize_srosr_expression(const details::operator_type &opr, expression_node_ptr(&branch)[2])
Definition: exprtk.hpp:33786
bool vob_optimisable(const details::operator_type &operation, expression_node_ptr(&branch)[2]) const
Definition: exprtk.hpp:25945
Definition: exprtk.hpp:4458
std::string branch_to_id(expression_node_ptr(&branch)[2])
Definition: exprtk.hpp:25854
Definition: exprtk.hpp:4149
bool join(const lexer::token &t0, const lexer::token &t1, const lexer::token &t2, lexer::token &t)
Definition: exprtk.hpp:3385
Definition: exprtk.hpp:4924
bool is_string_operation(const details::operator_type &operation, expression_node_ptr(&branch)[3])
Definition: exprtk.hpp:26069
Definition: exprtk.hpp:4402
Definition: exprtk.hpp:19263
details::range_pack< T > range_t
Definition: exprtk.hpp:18151
T0oT1oT2oT3(T0 p0, T1 p1, T2 p2, T3 p3, bfunc_t p4, bfunc_t p5, bfunc_t p6)
Definition: exprtk.hpp:13861
std::size_t vec_size_
Definition: exprtk.hpp:7475
bool sequence_check_enabled() const
Definition: exprtk.hpp:19430
bool operator==(const expression< T > &e)
Definition: exprtk.hpp:17732
~vectorize_node()
Definition: exprtk.hpp:9449
T value() const
Definition: exprtk.hpp:8640
Definition: exprtk.hpp:2018
expression_node< T >::node_type type() const
Definition: exprtk.hpp:13341
vector_holder< T > vector_holder_t
Definition: exprtk.hpp:7133
generic_function_ptr get_generic_function(const std::string &function_name) const
Definition: exprtk.hpp:16862
Definition: exprtk.hpp:13033
Definition: exprtk.hpp:4401
expression_node< T >::node_type type() const
Definition: exprtk.hpp:6466
Definition: exprtk.hpp:4451
vds_t & vds()
Definition: exprtk.hpp:7047
bool verify(const std::string &param_seq, std::size_t &pseq_index)
Definition: exprtk.hpp:23146
vararg_node(const Sequence< expression_ptr, Allocator > &arg_list)
Definition: exprtk.hpp:9332
covocov_t::sf4_type sf4_type
Definition: exprtk.hpp:32424
bool is_vector(const std::string &vector_name) const
Definition: exprtk.hpp:18903
const range_t & range_ref() const
Definition: exprtk.hpp:8828
void set_sf4m(sf4_map_t &sf4_map)
Definition: exprtk.hpp:25544
std::vector< const T * > arg_list_
Definition: exprtk.hpp:9426
static T process(const std::string &t1, const std::string &t2)
Definition: exprtk.hpp:12084
expression_node_ptr parse_function_invocation(ifunction< T > *function, const std::string &function_name)
Definition: exprtk.hpp:20841
freefunc11(ff11_functor ff)
Definition: exprtk.hpp:16141
T0 t0_
Definition: exprtk.hpp:14213
Definition: exprtk.hpp:12028
Definition: exprtk.hpp:4920
Definition: exprtk.hpp:4454
println(const std::string &scalar_format="%10.5f")
Definition: exprtk.hpp:36539
std::size_t get_vector_list(Sequence< std::string, Allocator > &vlist) const
Definition: exprtk.hpp:17301
T value() const
Definition: exprtk.hpp:5907
T xor_impl(const T v0, const T v1, real_type_tag)
Definition: exprtk.hpp:1148
~switch_node()
Definition: exprtk.hpp:6619
const T & Type
Definition: exprtk.hpp:2001
std::pair< expression_ptr, bool > branch_t
Definition: exprtk.hpp:5946
read< T > r
Definition: exprtk.hpp:37048
std::size_t vector_count() const
Definition: exprtk.hpp:16803
parser_helper prsrhlpr_t
Definition: exprtk.hpp:18223
scor_node(const operator_type &opr, expression_ptr branch0, expression_ptr branch1)
Definition: exprtk.hpp:11001
function & var(const std::string &v)
Definition: exprtk.hpp:35480
void advance_token(const token_advance_mode mode)
Definition: exprtk.hpp:4008
Definition: exprtk.hpp:6269
std::vector< data_pack > local_data_list_t
Definition: exprtk.hpp:17596
std::vector< type_store_t > ts_list_t
Definition: exprtk.hpp:4371
expression_node< T >::node_type type() const
Definition: exprtk.hpp:9307
str_base_ptr str0_base_ptr_
Definition: exprtk.hpp:8721
igfun_t::generic_type generic_type
Definition: exprtk.hpp:38124
vocovoc_t::sf4_type sf4_type
Definition: exprtk.hpp:31975
T erf_impl(T v, int_type_tag)
Definition: exprtk.hpp:1222
str_xoxr_node(SType0 p0, SType1 p1, RangePack rp1)
Definition: exprtk.hpp:14836
virtual std::string str() const =0
static expression_node< T >::node_type type()
Definition: exprtk.hpp:12189
assignment_op_node(const operator_type &opr, expression_ptr branch0, expression_ptr branch1)
Definition: exprtk.hpp:9909
std::vector< T > value_list_
Definition: exprtk.hpp:11405
Definition: exprtk.hpp:4438
symbol_type
Definition: exprtk.hpp:19053
expression_node_ptr parse_string_function_call(igeneric_function< T > *function, const std::string &function_name)
Definition: exprtk.hpp:23460
branch_t branch_[1]
Definition: exprtk.hpp:15264
const bool alternative_deletable_
Definition: exprtk.hpp:6035
Definition: exprtk.hpp:36865
virtual ~T0oT1oT2oT3_base_node()
Definition: exprtk.hpp:13269
igfun_t::parameter_list_t parameter_list_t
Definition: exprtk.hpp:36818
T value() const
Definition: exprtk.hpp:14612
const T & type
Definition: exprtk.hpp:35721
bool collect_assignments_
Definition: exprtk.hpp:19212
scope_element null_element_
Definition: exprtk.hpp:18504
bfunc_t f1() const
Definition: exprtk.hpp:13901
T operator()(const std::size_t &ps_index, parameter_list_t parameters)
Definition: exprtk.hpp:37351
bool all_nodes_valid(const Sequence< expression_node< T > *, Allocator > &b)
Definition: exprtk.hpp:5156
T nor_opr(const T v0, const T v1)
Definition: exprtk.hpp:1503
scand_node(const operator_type &opr, expression_ptr branch0, expression_ptr branch1)
Definition: exprtk.hpp:10977
static T process_6(const Sequence &arg_list)
Definition: exprtk.hpp:12794
type_checker(parser_t &p, const std::string &func_name, const std::string &param_seq)
Definition: exprtk.hpp:23136
while_loop_node(expression_ptr condition, expression_ptr loop_body)
Definition: exprtk.hpp:6170
virtual std::size_t size() const =0
std::size_t size
Definition: exprtk.hpp:18298
Definition: exprtk.hpp:13070
details::generic_string_range_node< T > generic_string_range_node_t
Definition: exprtk.hpp:18157
stringvar_node< T > * strvar_node_ptr
Definition: exprtk.hpp:8448
static expression_node< T >::node_type type()
Definition: exprtk.hpp:12055
expression_node_ptr cardinal_pow_optimisation(expression_node_ptr(&branch)[2])
Definition: exprtk.hpp:28090
Definition: exprtk.hpp:35155
expression_node_ptr simplify(Sequence< expression_node_ptr, Allocator1 > &expression_list, Sequence< bool, Allocator2 > &side_effect_list, const bool specialise_on_final_type=false)
Definition: exprtk.hpp:22441
opr_base< T >::Type Type
Definition: exprtk.hpp:12006
std::string * value_
Definition: exprtk.hpp:7645
T csc_impl(const T v, real_type_tag)
Definition: exprtk.hpp:1306
T atan_impl(const T v, real_type_tag)
Definition: exprtk.hpp:1287
details::assignment_string_range_node< T > assignment_string_range_node_t
Definition: exprtk.hpp:18160
Definition: exprtk.hpp:4435
string_base_node< T > * str_base_ptr
Definition: exprtk.hpp:7856
details::vector_holder< T > * vector_holder_ptr
Definition: exprtk.hpp:17562
static T process_3(const Sequence &arg_list)
Definition: exprtk.hpp:12537
std::string & s0()
Definition: exprtk.hpp:14743
Definition: exprtk.hpp:2024
T value() const
Definition: exprtk.hpp:6190
static T process(const T &t0, const T &t1, const T &t2)
Definition: exprtk.hpp:12207
virtual bool result()
Definition: exprtk.hpp:2857
std::string data_
Definition: exprtk.hpp:414
bool add_constant(const std::string &constant_name, const T &value)
Definition: exprtk.hpp:16986
irange_ptr str0_range_ptr_
Definition: exprtk.hpp:8723
generic_type::scalar_view scalar_t
Definition: exprtk.hpp:37383
expression< T > & operator=(const expression< T > &e)
Definition: exprtk.hpp:17707
details::T0oT1oT2oT3_define< T, const_t, cref_t, cref_t, cref_t > covovov_t
Definition: exprtk.hpp:18214
bool is_null_present(expression_node_ptr(&branch)[2]) const
Definition: exprtk.hpp:26093
bool local_variable_is_shadowed(const std::string &symbol)
Definition: exprtk.hpp:24154
const T & v_
Definition: exprtk.hpp:14438
expression_node< T > * expression_ptr
Definition: exprtk.hpp:6591
control_block * control_block_
Definition: exprtk.hpp:17548
T * data_t
Definition: exprtk.hpp:4547
static T process_4(const Sequence &arg_list)
Definition: exprtk.hpp:12347
IFunction ifunction
Definition: exprtk.hpp:11026
static T_ execute(ifunction &f, T_(&v)[17])
Definition: exprtk.hpp:11183
bool retinv_null
Definition: exprtk.hpp:17679
GenericFunction * function_
Definition: exprtk.hpp:11588
Definition: exprtk.hpp:4924
T value() const
Definition: exprtk.hpp:6444
virtual std::string & ref()
Definition: exprtk.hpp:7618
T value() const
Definition: exprtk.hpp:7266
igfun_t::generic_type generic_type
Definition: exprtk.hpp:37640
static T process(const arg_list_t &arg)
Definition: exprtk.hpp:26630
Definition: exprtk.hpp:4430
T root(const T v0, const T v1)
Definition: exprtk.hpp:1440
expression_node_ptr parse_vararg_function()
Definition: exprtk.hpp:22284
Definition: exprtk.hpp:7312
settings_store & enable_all_arithmetic_ops()
Definition: exprtk.hpp:19341
Definition: exprtk.hpp:13530
Definition: exprtk.hpp:37193
bool synthesize_expression(const details::operator_type &operation, expression_node_ptr(&branch)[2], expression_node_ptr &result)
Definition: exprtk.hpp:29049
Operation operation_t
Definition: exprtk.hpp:13281
range_t * range_ptr
Definition: exprtk.hpp:8078
literal_node(literal_node< T > &)
Definition: exprtk.hpp:5535
type_store< T > generic_type
Definition: exprtk.hpp:11790
const std::size_t size_
Definition: exprtk.hpp:7307
range_ptr str1_range_ptr_
Definition: exprtk.hpp:8437
bool return_present() const
Definition: exprtk.hpp:19152
std::string str() const
Definition: exprtk.hpp:7806
opr_base< T >::Type Type
Definition: exprtk.hpp:12158
range_pack< T > range_t
Definition: exprtk.hpp:8334
Definition: exprtk.hpp:4916
store_type
Definition: exprtk.hpp:4146
expression_node< T >::node_type type() const
Definition: exprtk.hpp:7361
bool valid() const
Definition: exprtk.hpp:18569
expression_node< T >::node_type type() const
Definition: exprtk.hpp:14149
static T process(const std::string &t1, const std::string &t2)
Definition: exprtk.hpp:12094
T value() const
Definition: exprtk.hpp:9244
static T process(const ivector_ptr v)
Definition: exprtk.hpp:12835
Definition: exprtk.hpp:4455
static std::string id(expression_generator< Type > &expr_gen, const details::operator_type o0, const details::operator_type o1)
Definition: exprtk.hpp:30116
T value() const
Definition: exprtk.hpp:14360
Definition: exprtk.hpp:37973
vector_holder_t & vec_holder()
Definition: exprtk.hpp:7226
T0oT1oT2oT3_sf4(T0 p0, T1 p1, T2 p2, T3 p3, const qfunc_t p4)
Definition: exprtk.hpp:14141
static T evaluate(const Type x, const Type c7, const Type c6, const Type c5, const Type c4, const Type c3, const Type c2, const Type c1, const Type c0)
Definition: exprtk.hpp:35223
expression_node_ptr synthesize_assignment_operation_expression(const details::operator_type &operation, expression_node_ptr(&branch)[2])
Definition: exprtk.hpp:27618
cocov_t::type0 node_type
Definition: exprtk.hpp:30125
expression_node< T > * expression_ptr
Definition: exprtk.hpp:5653
ff10_functor f
Definition: exprtk.hpp:16134
T value() const
Definition: exprtk.hpp:14160
bool operator()(std::size_t &r0, std::size_t &r1, const std::size_t &size=std::numeric_limits< std::size_t >::max()) const
Definition: exprtk.hpp:6888
operator_type operation() const
Definition: exprtk.hpp:14370
expression_ptr return_
Definition: exprtk.hpp:6139
T value() const
Definition: exprtk.hpp:5476
Definition: exprtk.hpp:4400
BaseFuncType & bft_
Definition: exprtk.hpp:35729
Definition: exprtk.hpp:18231
Definition: exprtk.hpp:17971
std::string & s1()
Definition: exprtk.hpp:14873
virtual operator_type operation() const
Definition: exprtk.hpp:13217
str_xroxr_node< T, SType0, SType1, RangePack, Operation > & operator=(str_xroxr_node< T, SType0, SType1, RangePack, Operation > &)
lexer::helper::commutative_inserter commutative_inserter_
Definition: exprtk.hpp:34675
covov_t::type0 node_type
Definition: exprtk.hpp:29777
symbol_table_t & symbol_table()
Definition: exprtk.hpp:35916
Definition: exprtk.hpp:18113
covovoc_t::sf4_type sf4_type
Definition: exprtk.hpp:33511
Definition: exprtk.hpp:4446
Definition: exprtk.hpp:15948
Definition: exprtk.hpp:4446
static expression_node_ptr process(expression_generator< Type > &expr_gen, const details::operator_type &operation, expression_node_ptr(&branch)[2])
Definition: exprtk.hpp:31459
std::set< std::string > reserved_symbol_table_
Definition: exprtk.hpp:16652
bool strength_reduction_enabled() const
Definition: exprtk.hpp:19431
bool run_scanners(lexer::generator &g)
Definition: exprtk.hpp:3915
void load_inv_binary_operations_map(inv_binary_op_map_t &m)
Definition: exprtk.hpp:34532
Definition: exprtk.hpp:4420
T value() const
Definition: exprtk.hpp:17757
bool to_uint(UIntType &u) const
Definition: exprtk.hpp:4305
~expression()
Definition: exprtk.hpp:17752
expression_node< T > * expression_ptr
Definition: exprtk.hpp:6669
shift_right< T > sr
Definition: exprtk.hpp:38176
std::size_t size
Definition: exprtk.hpp:16219
generic_type::scalar_view scalar_t
Definition: exprtk.hpp:36895
static expression_node< T >::node_type type()
Definition: exprtk.hpp:12045
bool return_invoked_
Definition: exprtk.hpp:11896
Definition: exprtk.hpp:37043
vector_node_ptr vec()
Definition: exprtk.hpp:9718
static T process(const Sequence< Type, Allocator > &arg_list)
Definition: exprtk.hpp:12728
generic_type::vector_view vector_t
Definition: exprtk.hpp:37292
#define exprtk_process_digit
expression_node_ptr synthesize_csocs_expression(const details::operator_type &opr, expression_node_ptr(&branch)[2])
Definition: exprtk.hpp:33866
bool enable_collect_assings_
Definition: exprtk.hpp:19798
functor_t::tfunc_t tfunc_t
Definition: exprtk.hpp:14048
symbol_table< T > & get_symbol_table(const std::size_t &index=0)
Definition: exprtk.hpp:17787
Definition: exprtk.hpp:4921
lexer::helper::symbol_replacer symbol_replacer_
Definition: exprtk.hpp:34678
Definition: exprtk.hpp:4439
ufunc_t f()
Definition: exprtk.hpp:13371
igfun_t::parameter_list_t parameter_list_t
Definition: exprtk.hpp:37152
static void process(std::pair< expression_node< T > *, bool >(&branch)[N], expression_node< T > *b)
Definition: exprtk.hpp:5716
generator_t & lexer()
Definition: exprtk.hpp:3970
static std::string id(expression_generator< Type > &expr_gen, const details::operator_type o0, const details::operator_type o1, const details::operator_type o2)
Definition: exprtk.hpp:33219
vec_data_store< T > vds_t
Definition: exprtk.hpp:9640
const bfunc_t f2_
Definition: exprtk.hpp:13942
std::size_t size() const
Definition: exprtk.hpp:10795
T value() const
Definition: exprtk.hpp:13973
bool is_invalid(const char_t c)
Definition: exprtk.hpp:152
freefunc09(ff09_functor ff)
Definition: exprtk.hpp:16119
T value() const
Definition: exprtk.hpp:10983
bool initialised_
Definition: exprtk.hpp:7977
static expression_node< T >::node_type type()
Definition: exprtk.hpp:12133
Definition: exprtk.hpp:15838
Definition: exprtk.hpp:4444
static expression_node< T > * allocate(Allocator &allocator, T0 p0, T1 p1, bfunc_t p2)
Definition: exprtk.hpp:13737
const range_t & range_ref() const
Definition: exprtk.hpp:7548
operator_type operation_
Definition: exprtk.hpp:5975
static std::string id()
Definition: exprtk.hpp:13520
#define basic_opr_switch_statements
Definition: exprtk.hpp:28012
details::binary_node< T > binary_node_t
Definition: exprtk.hpp:18132
token & set_string(const std::string &s, const std::size_t p)
Definition: exprtk.hpp:2088
ivariable_ptr var1_
Definition: exprtk.hpp:7369
Definition: exprtk.hpp:35493
variable_node_t * variable_node_ptr
Definition: exprtk.hpp:18237
~scoped_vec_delete()
Definition: exprtk.hpp:20791
static details::operator_type operation()
Definition: exprtk.hpp:12096
Definition: exprtk.hpp:4434
str_sogens_node< T, Operation > & operator=(str_sogens_node< T, Operation > &)
void free_all_nodes(NodeAllocator &node_allocator, Sequence< expression_node< T > *, Allocator > &b)
Definition: exprtk.hpp:5209
expression_node< T >::node_type type() const
Definition: exprtk.hpp:8207
rebasevector_elem_node(expression_ptr index, vector_holder_ptr vec_holder)
Definition: exprtk.hpp:7137
static std::string id(expression_generator< Type > &expr_gen, const details::operator_type o0, const details::operator_type o1, const details::operator_type o2)
Definition: exprtk.hpp:33442
exprtk::parser< T > parser_t
Definition: exprtk.hpp:35397
bool is_rebasevector_elem_node(const expression_node< T > *node)
Definition: exprtk.hpp:5039
static expression_node_ptr process(expression_generator< Type > &expr_gen, const details::operator_type &operation, expression_node_ptr(&branch)[2])
Definition: exprtk.hpp:29720
T shr(const T v0, const T v1)
Definition: exprtk.hpp:1468
char_cptr base() const
Definition: exprtk.hpp:8406
Definition: exprtk.hpp:4452
const bool branch_deletable_
Definition: exprtk.hpp:5505
multimode_genfunction_node(GenericFunction *func, const std::size_t &param_seq_index, const std::vector< typename gen_function_t::expression_ptr > &arg_list)
Definition: exprtk.hpp:11693
void dump(lexer::generator &generator)
Definition: exprtk.hpp:3158
token & set_operator(const token_type tt, const Iterator begin, const Iterator end, const Iterator base_begin=Iterator(0))
Definition: exprtk.hpp:2047
bool destruct
Definition: exprtk.hpp:4616
Definition: exprtk.hpp:4420
Definition: exprtk.hpp:4448
vococ_t::sf3_type sf3_type
Definition: exprtk.hpp:30249
T1 t1_
Definition: exprtk.hpp:13840
std::pair< bool, expression_node_ptr > n0_e
Definition: exprtk.hpp:6942
expression_node_ptr parse_string()
Definition: exprtk.hpp:22782
static details::operator_type operation()
Definition: exprtk.hpp:12035
T0 t0() const
Definition: exprtk.hpp:14074
all_true< T > at
Definition: exprtk.hpp:38167
covovov_t::sf4_type sf4_type
Definition: exprtk.hpp:33342
void store_token()
Definition: exprtk.hpp:3980
bool is_vector_elem_node(const expression_node< T > *node)
Definition: exprtk.hpp:5033
vovocov_t::type3 node_type
Definition: exprtk.hpp:32723
Definition: exprtk.hpp:12831
expression_node< T > * branch(const std::size_t &) const
Definition: exprtk.hpp:5497
st_data * data_
Definition: exprtk.hpp:16700
static std::string id(expression_generator< Type > &expr_gen, const details::operator_type o0, const details::operator_type o1, const details::operator_type o2)
Definition: exprtk.hpp:33499
vector_node_ptr vec()
Definition: exprtk.hpp:10785
std::vector< T > tmp_vs_t
Definition: exprtk.hpp:11424
expression_node< T > * expression_ptr
Definition: exprtk.hpp:6422
Definition: exprtk.hpp:4917
freefunc10(ff10_functor ff)
Definition: exprtk.hpp:16130
bool valid_string_operation(const details::operator_type &operation) const
Definition: exprtk.hpp:25742
Definition: exprtk.hpp:8258
static std::string id(expression_generator< Type > &expr_gen, const details::operator_type o0, const details::operator_type o1, const details::operator_type o2)
Definition: exprtk.hpp:32412
char_cptr base() const
Definition: exprtk.hpp:7811
literal_node< T > & operator=(literal_node< T > &)
Definition: exprtk.hpp:5536
static std::string id(expression_generator< Type > &expr_gen, const details::operator_type o0, const details::operator_type o1, const details::operator_type o2)
Definition: exprtk.hpp:33386
static const std::string logic_ops_list[]
Definition: exprtk.hpp:462
const vds_t & vds() const
Definition: exprtk.hpp:7466
multi_switch_node(const Sequence< expression_ptr, Allocator > &arg_list)
Definition: exprtk.hpp:6692
#define exprtk_crtype(Type)
Definition: exprtk.hpp:13457
vector_node_ptr vec()
Definition: exprtk.hpp:9868
settings_control_structs
Definition: exprtk.hpp:19269
IFunction ifunction
Definition: exprtk.hpp:11317
std::vector< lexer::token_modifier * > token_modifier_list
Definition: exprtk.hpp:3938
bipow_node< T, PowOp > & operator=(const bipow_node< T, PowOp > &)
std::map< std::string, synthesize_functor_t > synthesize_map_t
Definition: exprtk.hpp:25441
details::quaternary_node< T > quaternary_node_t
Definition: exprtk.hpp:18134
Definition: exprtk.hpp:4220
local_data_t & local_data(const std::size_t &index=0)
Definition: exprtk.hpp:18941
T0 t0() const
Definition: exprtk.hpp:13791
std::size_t stringvar_count() const
Definition: exprtk.hpp:16786
covocov_t::type4 node_type
Definition: exprtk.hpp:33397
T operator()(const std::size_t &ps_index, parameter_list_t parameters)
Definition: exprtk.hpp:37850
std::size_t next_ip_index()
Definition: exprtk.hpp:18469
Definition: exprtk.hpp:4397
expression_node_ptr synthesize_socs_expression(const details::operator_type &opr, expression_node_ptr(&branch)[2])
Definition: exprtk.hpp:33802
boc_node< T, Operation > & operator=(const boc_node< T, Operation > &)
Definition: exprtk.hpp:19256
str_sogens_node(const operator_type &opr, expression_ptr branch0, expression_ptr branch1)
Definition: exprtk.hpp:14978
exprtk::igeneric_function< T > igfun_t
Definition: exprtk.hpp:38028
bool initialised_
Definition: exprtk.hpp:8720
type_store()
Definition: exprtk.hpp:16221
generic_type::vector_view vector_t
Definition: exprtk.hpp:37836
Definition: exprtk.hpp:4426
igfun_t::parameter_list_t parameter_list_t
Definition: exprtk.hpp:38077
void deactivate(const std::size_t &scope_depth)
Definition: exprtk.hpp:18410
static T process(const T &t0, const T &t1, const T &t2, const bfunc_t bf0, const bfunc_t bf1)
Definition: exprtk.hpp:13468
vob_node(const T &var, const expression_ptr brnch)
Definition: exprtk.hpp:14501
generic_type::scalar_view scalar_t
Definition: exprtk.hpp:37698
std::map< std::string, type_pair_t, details::ilesscompare > type_map_t
Definition: exprtk.hpp:16212
void set_c(const T new_c)
Definition: exprtk.hpp:14627
string_function_node(StringFunction *func, const std::vector< typename gen_function_t::expression_ptr > &arg_list)
Definition: exprtk.hpp:11610
T value() const
Definition: exprtk.hpp:6523
T0oT1oT2_sf3ext< T, T0, T1, T2, SF3Operation > node_type
Definition: exprtk.hpp:14050
scope_element & get_element(const std::size_t &index)
Definition: exprtk.hpp:18336
bool imatch(const char_t c1, const char_t c2)
Definition: exprtk.hpp:174
irange_ptr str_range_ptr_
Definition: exprtk.hpp:7842
#define case_stmt1(op)
static expression_node_ptr error_node()
Definition: exprtk.hpp:20705
Definition: exprtk.hpp:4452
T value() const
Definition: exprtk.hpp:10403
range_pack< T > range_t
Definition: exprtk.hpp:7996
expression_node< T > * expression_ptr
Definition: exprtk.hpp:15080
vec_data_store()
Definition: exprtk.hpp:4634
std::vector< expression_ptr > initialiser_list_
Definition: exprtk.hpp:7306
synthesize_map_t synthesize_map_
Definition: exprtk.hpp:34362
vector_holder(exprtk::vector_view< Type > &vec)
Definition: exprtk.hpp:5404
Definition: exprtk.hpp:4330
const T & v2_
Definition: exprtk.hpp:9285
T roundn_impl(const T v0, const T v1, real_type_tag)
Definition: exprtk.hpp:1018
Definition: exprtk.hpp:4923
binary_node(const operator_type &opr, expression_ptr branch0, expression_ptr branch1)
Definition: exprtk.hpp:5787
Definition: exprtk.hpp:15134
Definition: exprtk.hpp:4411
functor_t::bfunc_t bfunc_t
Definition: exprtk.hpp:13852
bool post_bracket_process(const typename token_t::token_type &token, expression_node_ptr &branch)
Definition: exprtk.hpp:24809
bool has_side_effects_
Definition: exprtk.hpp:15788
generic_type::vector_view vector_t
Definition: exprtk.hpp:37246
T value() const
Definition: exprtk.hpp:11007
bool register_modifier(lexer::token_modifier *modifier)
Definition: exprtk.hpp:3807
static std::string id(expression_generator< Type > &expr_gen, const details::operator_type o0, const details::operator_type o1)
Definition: exprtk.hpp:29467
vector_node< T > * vec1_node_ptr_
Definition: exprtk.hpp:7474
ff09_functor f
Definition: exprtk.hpp:16123
variable_ptr get_variable(const std::string &variable_name) const
Definition: exprtk.hpp:18599
Definition: exprtk.hpp:2029
shift_left< T > sl
Definition: exprtk.hpp:38175
usr_mode mode
Definition: exprtk.hpp:19013
expression_node< T >::node_type type() const
Definition: exprtk.hpp:10942
void dump_ptr(const std::string &, const void *)
Definition: exprtk.hpp:4537
const char_t & back(const std::string &s)
Definition: exprtk.hpp:256
igfun_t::generic_type generic_type
Definition: exprtk.hpp:37697
expression_node< T >::node_type type() const
Definition: exprtk.hpp:5523
opr_base< T >::Type Type
Definition: exprtk.hpp:12092
Definition: exprtk.hpp:12060
void add_assignment(const std::string &symbol, const symbol_type st)
Definition: exprtk.hpp:19194
T0oT1oT2< T, T0, T1, T2, ProcessMode > node_type
Definition: exprtk.hpp:13764
expression_node_ptr parse_conditional_statement()
Definition: exprtk.hpp:21392
~function_N_node()
Definition: exprtk.hpp:11033
~vector_assignment_node()
Definition: exprtk.hpp:7255
Definition: exprtk.hpp:4912
Definition: exprtk.hpp:2022
std::string str() const
Definition: exprtk.hpp:8033
std::vector< type_store > & parameter_list_
Definition: exprtk.hpp:4214
T value() const
Definition: exprtk.hpp:14728
st_data()
Definition: exprtk.hpp:16613
const T c() const
Definition: exprtk.hpp:14683
sf4_node(const operator_type &opr, expression_ptr branch0, expression_ptr branch1, expression_ptr branch2, expression_ptr branch3)
Definition: exprtk.hpp:9236
tfunc_t f() const
Definition: exprtk.hpp:13993
vector_node_ptr vec()
Definition: exprtk.hpp:7446
all_true()
Definition: exprtk.hpp:37158
bool is_vov_node(const expression_node< T > *node)
Definition: exprtk.hpp:15268
Definition: exprtk.hpp:13443
operator_type operation() const
Definition: exprtk.hpp:5492
T0oT1oT2(T0 p0, T1 p1, T2 p2, const bfunc_t p3, const bfunc_t p4)
Definition: exprtk.hpp:13767
static expression_node_ptr process(expression_generator< Type > &expr_gen, const details::operator_type &sf4opr, T0 t0, T1 t1, T2 t2, T3 t3)
Definition: exprtk.hpp:29220
T operator()(const std::size_t &ps_index, parameter_list_t parameters)
Definition: exprtk.hpp:37397
bool add_impl(const std::string &symbol_name, RType t, const bool is_const)
Definition: exprtk.hpp:16272
void ignore_symbol(const std::string &symbol)
Definition: exprtk.hpp:3181
Definition: exprtk.hpp:38165
Definition: exprtk.hpp:38024
Definition: exprtk.hpp:7342
Definition: exprtk.hpp:7849
lexer::token_joiner * error_token_joiner
Definition: exprtk.hpp:3944
void clear()
Definition: exprtk.hpp:19128
details::char_cptr base_itr_
Definition: exprtk.hpp:2841
bool is_constant_node(const std::string &symbol_name) const
Definition: exprtk.hpp:16918
Definition: exprtk.hpp:16053
range_t range_
Definition: exprtk.hpp:8725
value_ptr value_at(const std::size_t &index) const
Definition: exprtk.hpp:5331
vococ_t::type0 node_type
Definition: exprtk.hpp:30370
bool is_swap_node(const expression_node< T > *node)
Definition: exprtk.hpp:5105
type()
Definition: exprtk.hpp:17980
settings_store & disable_all_assignment_ops()
Definition: exprtk.hpp:19401
bool add_function(const std::string &function_name, function_t &function)
Definition: exprtk.hpp:17015
bool collect_variables_
Definition: exprtk.hpp:19210
variable_ptr get_variable(const T &var_ref) const
Definition: exprtk.hpp:16821
static std::string null_value
Definition: exprtk.hpp:8229
Definition: exprtk.hpp:4399
local_data_list_t local_data_list
Definition: exprtk.hpp:17677
string_function_node< T, StringFunction > str_function_t
Definition: exprtk.hpp:11734
T const_pi_impl(real_type_tag)
Definition: exprtk.hpp:1315
bool pgo_primer()
Definition: exprtk.hpp:36134
bool getline(std::string &s)
Definition: exprtk.hpp:36731
Definition: exprtk.hpp:12100
std::size_t vector_size() const
Definition: exprtk.hpp:5336
expression_ptr v_
Definition: exprtk.hpp:9476
Definition: exprtk.hpp:4918
unsigned long long int usec_time() const
Definition: exprtk.hpp:36397
const T & v() const
Definition: exprtk.hpp:13302
return_node(const std::vector< typename gen_function_t::expression_ptr > &arg_list, results_context_t &rc)
Definition: exprtk.hpp:11810
const bool test_deletable_
Definition: exprtk.hpp:6033
static T process(Type t1, Type t2)
Definition: exprtk.hpp:12053
#define register_sf3_extid(Id, Op)
details::char_t char_t
Definition: exprtk.hpp:2192
std::size_t paramseq_count() const
Definition: exprtk.hpp:23206
virtual operator_type operation() const
Definition: exprtk.hpp:13119
T value() const
Definition: exprtk.hpp:15249
bool add_pi()
Definition: exprtk.hpp:17232
std::pair< expression_ptr, bool > branch_t
Definition: exprtk.hpp:15169
expression_node< T > * expression_ptr
Definition: exprtk.hpp:13322
const T & v0() const
Definition: exprtk.hpp:14375
build_string(const std::size_t &initial_size=64)
Definition: exprtk.hpp:385
Definition: exprtk.hpp:4426
static T process(Type t1, Type t2)
Definition: exprtk.hpp:12159
expression_node_ptr parse_conditional_statement_01(expression_node_ptr condition)
Definition: exprtk.hpp:21148
expression_node< T > * expression_ptr
Definition: exprtk.hpp:10824
bool & collect_variables()
Definition: exprtk.hpp:19137
static bool compile_left(expression_generator< Type > &expr_gen, ExternalType t, const details::operator_type &operation, expression_node_ptr &sf3node, expression_node_ptr &result)
Definition: exprtk.hpp:29328
bool add(const std::string &symbol_name, std::vector< T, Allocator > &v, const bool is_const=false)
Definition: exprtk.hpp:16344
igfun_t::generic_type generic_type
Definition: exprtk.hpp:36950
expression_node_ptr parse_switch_statement()
Definition: exprtk.hpp:22023
T1 t1() const
Definition: exprtk.hpp:13881
variable_node< T > * var_node_ptr_
Definition: exprtk.hpp:9936
operator_type operation() const
Definition: exprtk.hpp:14617
struct timeval stop_time_
Definition: exprtk.hpp:36435
bool is_vector_arithmetic_operation(const details::operator_type &operation, expression_node_ptr(&branch)[2]) const
Definition: exprtk.hpp:26123
static const std::string base_function_list[]
Definition: exprtk.hpp:447
Definition: exprtk.hpp:12016
bool side_effect() const
Definition: exprtk.hpp:10162
bool is_variable(const std::string &variable_name) const
Definition: exprtk.hpp:18815
file_descriptor * make_handle(T v)
Definition: exprtk.hpp:36784
bool valid_function(const std::string &symbol) const
Definition: exprtk.hpp:17510
igfun_t::generic_type generic_type
Definition: exprtk.hpp:37199
ifunction * function_
Definition: exprtk.hpp:11343
T(* qfunc_t)(Type t0, Type t1, Type t2, Type t3)
Definition: exprtk.hpp:2003
static expression_node_ptr process(expression_generator< Type > &expr_gen, const details::operator_type &operation, expression_node_ptr(&branch)[2])
Definition: exprtk.hpp:33011
Definition: exprtk.hpp:10509
const range_t & range_ref() const
Definition: exprtk.hpp:7965
vovocov_t::sf4_type sf4_type
Definition: exprtk.hpp:32255
char_cptr base() const
Definition: exprtk.hpp:8693
expression_node< T > * expression_ptr
Definition: exprtk.hpp:8262
rebasevector_elem_node< T > * rbvec_node_ptr_
Definition: exprtk.hpp:10010
vector_holder_ptr vector_holder_
Definition: exprtk.hpp:7183
const type_store & back() const
Definition: exprtk.hpp:4207
Definition: exprtk.hpp:13276
Definition: exprtk.hpp:2017
Definition: exprtk.hpp:2969
Definition: exprtk.hpp:13447
const T & v() const
Definition: exprtk.hpp:14522
Definition: exprtk.hpp:2022
T or_opr(const T v0, const T v1)
Definition: exprtk.hpp:1496
functor_t::ufunc_t unary_functor_t
Definition: exprtk.hpp:18183
T value() const
Definition: exprtk.hpp:10032
igfun_t::generic_type generic_type
Definition: exprtk.hpp:36819
bool read(View &view, const std::size_t amount, const std::size_t offset=0)
Definition: exprtk.hpp:36713
generic_type::scalar_view scalar_t
Definition: exprtk.hpp:37529
generic_type::string_view string_t
Definition: exprtk.hpp:36951
details::functor_t< T > functor_t
Definition: exprtk.hpp:14225
branch_t branch_[2]
Definition: exprtk.hpp:5882
igfun_t::parameter_list_t parameter_list_t
Definition: exprtk.hpp:38029
T value() const
Definition: exprtk.hpp:14069
range_pack< T > range_t
Definition: exprtk.hpp:8742
expression_node< T > * expression_ptr
Definition: exprtk.hpp:7378
T value() const
Definition: exprtk.hpp:14912
std::size_t vector_size() const
Definition: exprtk.hpp:5375
bool is_assignment_operation(const details::operator_type &operation) const
Definition: exprtk.hpp:25729
static void execute(T_(&v)[BranchCount], const branch_t(&b)[BranchCount])
Definition: exprtk.hpp:11092
Definition: exprtk.hpp:16033
std::string & s0()
Definition: exprtk.hpp:14943
expression_node< T >::node_type type() const
Definition: exprtk.hpp:14858
expression_ptr consequent_
Definition: exprtk.hpp:8847
Definition: exprtk.hpp:18232
Definition: exprtk.hpp:4447
std::string get_variable_name(const expression_node_ptr &ptr) const
Definition: exprtk.hpp:18919
virtual const T & v() const =0
expression_node< T > * expression_ptr
Definition: exprtk.hpp:8740
variable_node< T > * var_node_ptr_
Definition: exprtk.hpp:9515
precedence_level right
Definition: exprtk.hpp:20405
static bool is_function(const expression< T > &expr)
Definition: exprtk.hpp:17948
vds_t vds_
Definition: exprtk.hpp:10505
T axn(T a, T x)
Definition: exprtk.hpp:8985
T value() const
Definition: exprtk.hpp:11625
bool is_const_string_range_node(const expression_node< T > *node)
Definition: exprtk.hpp:15334
expression_ptr loop_body_
Definition: exprtk.hpp:6348
Definition: exprtk.hpp:4446
ivariable< T > * ivariable_ptr
Definition: exprtk.hpp:7347
T value() const
Definition: exprtk.hpp:8930
~null_eq_node()
Definition: exprtk.hpp:5468
expression_node< T >::node_type type() const
Definition: exprtk.hpp:11768
T equal_impl(const T v0, const T v1, real_type_tag)
Definition: exprtk.hpp:873
bool valid_operator(const details::operator_type &operation, binary_functor_t &bop)
Definition: exprtk.hpp:25564
generic_type::vector_view vector_t
Definition: exprtk.hpp:37699
Definition: exprtk.hpp:4427
rol< T > rl
Definition: exprtk.hpp:38173
Definition: exprtk.hpp:4510
expression_node< T >::node_type type() const
Definition: exprtk.hpp:13414
strvar_node_ptr str0_node_ptr_
Definition: exprtk.hpp:8066
static std::string id(expression_generator< Type > &expr_gen, const details::operator_type o0, const details::operator_type o1, const details::operator_type o2)
Definition: exprtk.hpp:33275
range_interface< T > irange_t
Definition: exprtk.hpp:8452
std::string scalar_format_
Definition: exprtk.hpp:36529
expression_node< T >::node_type type() const
Definition: exprtk.hpp:10291
std::vector< expression_ptr > arg_list_
Definition: exprtk.hpp:11593
static expression_node_ptr process(expression_generator< Type > &expr_gen, const details::operator_type &operation, expression_node_ptr(&branch)[2])
Definition: exprtk.hpp:30506
vocovoc_t::type2 node_type
Definition: exprtk.hpp:32480
T value() const
Definition: exprtk.hpp:15145
static T process(const std::string &t1, const std::string &t2)
Definition: exprtk.hpp:12074
variable_node_ptr var1_
Definition: exprtk.hpp:7338
T operator()(parameter_list_t parameters)
Definition: exprtk.hpp:36523
details::T0oT1_define< T, cref_t, cref_t > vov_t
Definition: exprtk.hpp:18198
details::for_loop_bc_node< T > for_loop_bc_node_t
Definition: exprtk.hpp:18143
vector_holder< T > * vector_holder_ptr
Definition: exprtk.hpp:10516
base_ops_map_t base_ops_map_
Definition: exprtk.hpp:34664
static std::string id(expression_generator< Type > &expr_gen, const details::operator_type o0, const details::operator_type o1, const details::operator_type o2)
Definition: exprtk.hpp:32131
std::size_t type_size
Definition: exprtk.hpp:6969
static expression_node_ptr process(expression_generator< Type > &expr_gen, const details::operator_type &operation, expression_node_ptr(&branch)[2])
Definition: exprtk.hpp:32730
std::vector< token_t > token_list_t
Definition: exprtk.hpp:2190
bool collect_functions(const std::string &expr_str, Sequence< std::string, Allocator > &symbol_list)
Definition: exprtk.hpp:34763
T value() const
Definition: exprtk.hpp:13716
T1 t1() const
Definition: exprtk.hpp:13726
static T process(const Sequence< Type, Allocator > &arg_list)
Definition: exprtk.hpp:12236
static void execute(std::string &s, char_cptr data, const std::size_t size)
Definition: exprtk.hpp:8320
~repeat_until_loop_bc_node()
Definition: exprtk.hpp:6431
igeneric_function< T >::parameter_list_t parameter_list_t
Definition: exprtk.hpp:36513
range_t & range_ref()
Definition: exprtk.hpp:8823
static T process_2(const Sequence &arg_list)
Definition: exprtk.hpp:12267
bool is_variable_node(const expression_node< T > *node)
Definition: exprtk.hpp:5015
T type
Definition: exprtk.hpp:15958
Definition: exprtk.hpp:4397
cocov_t::sf3_type sf3_type
Definition: exprtk.hpp:30136
Definition: exprtk.hpp:4408
T value() const
Definition: exprtk.hpp:6312
Definition: exprtk.hpp:36346
expression_node< T > * branch(const std::size_t &) const
Definition: exprtk.hpp:13424
bool is_cov_node(const expression_node< T > *node)
Definition: exprtk.hpp:15274
operator_type operation() const
Definition: exprtk.hpp:14064
bool write(const View &view, const std::size_t amount, const std::size_t offset=0)
Definition: exprtk.hpp:36694
Definition: exprtk.hpp:9903
static float value()
Definition: exprtk.hpp:807
bool post_variable_process(const std::string &symbol)
Definition: exprtk.hpp:24784
T or_impl(const T v0, const T v1, int_type_tag)
Definition: exprtk.hpp:1130
Definition: exprtk.hpp:4935
static T process_8(const Sequence &arg_list)
Definition: exprtk.hpp:12817
function_ptr get_function(const std::string &function_name) const
Definition: exprtk.hpp:18661
static T process(const T &t0, const T &t1, const T &t2, const T &t3, const bfunc_t bf0, const bfunc_t bf1, const bfunc_t bf2)
Definition: exprtk.hpp:13573
const std::string value_
Definition: exprtk.hpp:5643
T xor_opr(const T v0, const T v1)
Definition: exprtk.hpp:1510
Definition: exprtk.hpp:9256
Definition: exprtk.hpp:13661
T value() const
Definition: exprtk.hpp:6727
void free_all_nodes(NodeAllocator &node_allocator, expression_node< T > *(&b)[N])
Definition: exprtk.hpp:5197
Definition: exprtk.hpp:12229
virtual bool rebaseable() const
Definition: exprtk.hpp:5363
Definition: exprtk.hpp:4911
lexer::helper::bracket_checker bracket_checker_
Definition: exprtk.hpp:34679
break_node(expression_ptr ret=expression_ptr(0))
Definition: exprtk.hpp:6111
Definition: exprtk.hpp:4917
vector_holder_ptr temp_
Definition: exprtk.hpp:10658
vector_node< T > * vector_node_ptr
Definition: exprtk.hpp:6980
exprtk::igeneric_function< T > igfun_t
Definition: exprtk.hpp:36817
T value() const
Definition: exprtk.hpp:6677
virtual bool rebaseable() const
Definition: exprtk.hpp:5272
expression_node< T > * expression_ptr
Definition: exprtk.hpp:13393
rebasevector_celem_node< T > * rbvec_node_ptr_
Definition: exprtk.hpp:9629
Definition: exprtk.hpp:4432
T value_type
Definition: exprtk.hpp:13853
vector_node< T > * vec1_node_ptr_
Definition: exprtk.hpp:9896
freefunc12(ff12_functor ff)
Definition: exprtk.hpp:16152
range_t range_
Definition: exprtk.hpp:11680
bool is_logic_opr(const std::string &lgc_opr)
Definition: exprtk.hpp:552
generic_type::vector_view vector_t
Definition: exprtk.hpp:36896
int to_int32(const T v)
Definition: exprtk.hpp:1370
details::operator_type get_operator(const binary_functor_t &bop)
Definition: exprtk.hpp:25588
static details::operator_type operation()
Definition: exprtk.hpp:12024
static std::string id()
Definition: exprtk.hpp:13582
vector_node< T > * vector_node_ptr
Definition: exprtk.hpp:10670
std::vector< funcparam_t > fp_map_
Definition: exprtk.hpp:36129
std::size_t stack_depth
Definition: exprtk.hpp:35702
static expression_node< T >::node_type type()
Definition: exprtk.hpp:12169
inv_binary_op_map_t inv_binary_op_map_
Definition: exprtk.hpp:34667
Definition: exprtk.hpp:14891
expression_node< T >::node_type type() const
Definition: exprtk.hpp:6568
const std::size_t stride_
Definition: exprtk.hpp:2966
expression_node< T > * expression_ptr
Definition: exprtk.hpp:14769
vocovoc_t::type3 node_type
Definition: exprtk.hpp:32947
covocov_t::type0 node_type
Definition: exprtk.hpp:30835
exprtk::igeneric_function< T > igfun_t
Definition: exprtk.hpp:37789
covovov_t::type3 node_type
Definition: exprtk.hpp:32835
T0 t0_
Definition: exprtk.hpp:14021
expression_node< T >::node_type type() const
Definition: exprtk.hpp:6811
static expression_node_ptr process(expression_generator< Type > &expr_gen, const details::operator_type &operation, expression_node_ptr(&branch)[2])
Definition: exprtk.hpp:29840
std::string type_id() const
Definition: exprtk.hpp:13911
range_t & range_ref()
Definition: exprtk.hpp:8703
static const char * date
Definition: exprtk.hpp:38241
Definition: exprtk.hpp:4396
bool empty() const
Definition: exprtk.hpp:4172
Definition: exprtk.hpp:7239
const range_t & range_ref() const
Definition: exprtk.hpp:7826
dependent_entity_collector & dec()
Definition: exprtk.hpp:20174
const T & v0_
Definition: exprtk.hpp:9283
bool remove_stringvar(const std::string &string_name)
Definition: exprtk.hpp:17192
T shr_impl(const T v0, const T v1, real_type_tag)
Definition: exprtk.hpp:1060
expression_node< T > * expression_ptr
Definition: exprtk.hpp:15168
char_t const * char_cptr
Definition: exprtk.hpp:91
Definition: exprtk.hpp:8575
virtual T operator()() empty_method_body inline virtual T operator()(const T &) empty_method_body inline virtual T operator()(const T &
base_operation_t(const operator_type t, const unsigned int &np)
Definition: exprtk.hpp:4493
vector_interface< T > * ivector_ptr
Definition: exprtk.hpp:12934
Definition: exprtk.hpp:4433
T * value_
Definition: exprtk.hpp:6818
quaternary_node(const operator_type &opr, expression_ptr branch0, expression_ptr branch1, expression_ptr branch2, expression_ptr branch3)
Definition: exprtk.hpp:5948
bool cob_optimisable(const details::operator_type &operation, expression_node_ptr(&branch)[2]) const
Definition: exprtk.hpp:25886
static details::operator_type operation()
Definition: exprtk.hpp:12143
covovoc_t::type2 node_type
Definition: exprtk.hpp:32536
unary_node(const operator_type &opr, expression_ptr brnch)
Definition: exprtk.hpp:5655
x y t t *t x y t t t x y t t t x *y t *t t x *y t *t t x y t t t x y t t t x(y+z)
static const std::size_t reserved_symbols_size
Definition: exprtk.hpp:445
T nequal_impl(const T v0, const T v1, real_type_tag)
Definition: exprtk.hpp:908
void enable_has_side_effects(FunctionType &func)
Definition: exprtk.hpp:15811
expression_ptr condition_
Definition: exprtk.hpp:6209
virtual ~vector_holder_base()
Definition: exprtk.hpp:5255
vds_t & vds()
Definition: exprtk.hpp:10301
vector_node< T > * vec_node_ptr_
Definition: exprtk.hpp:10169
void cleanup_escapes(std::string &s)
Definition: exprtk.hpp:335
vds_t & vds()
Definition: exprtk.hpp:10488
range_pack< T > range_t
Definition: exprtk.hpp:11691
Definition: exprtk.hpp:37026
unsigned int num_params
Definition: exprtk.hpp:4499
std::string get_conststr_stringvar_name(const expression_ptr &ptr) const
Definition: exprtk.hpp:17407
vocov_t::type0 node_type
Definition: exprtk.hpp:29657
void next_token()
Definition: exprtk.hpp:3992
freefunc14(ff14_functor ff)
Definition: exprtk.hpp:16176
const bool index_deletable_
Definition: exprtk.hpp:7123
static expression_node< T >::node_type type()
Definition: exprtk.hpp:12085
Definition: exprtk.hpp:4445
static void assign(RefType t1, Type t2)
Definition: exprtk.hpp:11986
T & ref()
Definition: exprtk.hpp:7211
vector_view(data_ptr_t data, const std::size_t &size)
Definition: exprtk.hpp:4070
bool is_nan_impl(const T v, real_type_tag)
Definition: exprtk.hpp:825
token_t current_token_
Definition: exprtk.hpp:4058
function_compositor(const symbol_table_t &st)
Definition: exprtk.hpp:35904
expression_node< T >::node_type type() const
Definition: exprtk.hpp:14237
void reset()
Definition: exprtk.hpp:3506
type_store< typename details::variable_node< T >, T > variable_store
Definition: exprtk.hpp:16603
std::string & s1()
Definition: exprtk.hpp:14748
igfun_t::generic_type generic_type
Definition: exprtk.hpp:37583
details::T0oT1oT2oT3< T, T0, T1, T2, T3, typename T0oT1oT20T3process< T >::mode1 > type1
Definition: exprtk.hpp:14339
T1 t1() const
Definition: exprtk.hpp:14258
vovovoc_t::sf4_type sf4_type
Definition: exprtk.hpp:31693
bool is_string_assignment_node(const expression_node< T > *node)
Definition: exprtk.hpp:15340
static std::string id(expression_generator< Type > &expr_gen, const details::operator_type o0, const details::operator_type o1, const details::operator_type o2)
Definition: exprtk.hpp:33106
sosos_node< T, SType0, SType1, SType2, Operation > & operator=(sosos_node< T, SType0, SType1, SType2, Operation > &)
static T_ execute(ifunction &f, T_(&v)[8])
Definition: exprtk.hpp:11246
static std::pair< bool, vector_t * > make(std::pair< T *, std::size_t > v, const bool is_const=false)
Definition: exprtk.hpp:16298
void clear()
Definition: exprtk.hpp:18564
bool assignment_enabled(const details::operator_type &assignment)
Definition: exprtk.hpp:19472
Definition: exprtk.hpp:16126
vector_holder_ptr vec_holder_
Definition: exprtk.hpp:7121
Definition: exprtk.hpp:18229
vds_t vds_
Definition: exprtk.hpp:10815
std::string src_location
Definition: exprtk.hpp:17989
bool simplify_unary_negation_branch(expression_node_ptr &node)
Definition: exprtk.hpp:20650
Definition: exprtk.hpp:2018
expression_node< typename node_type::value_type > * allocate_rrr(T1 &t1, T2 &t2, T3 &t3) const
Definition: exprtk.hpp:15524
T & ref()
Definition: exprtk.hpp:7098
std::size_t size
Definition: exprtk.hpp:6968
details::char_cptr s_end_
Definition: exprtk.hpp:2843
bool bracket_check_enabled() const
Definition: exprtk.hpp:19429
virtual ~igeneric_function()
Definition: exprtk.hpp:15967
ff07_functor f
Definition: exprtk.hpp:16101
details::functor_t< T > functor_t
Definition: exprtk.hpp:18179
vector_holder< T > * vector_holder_ptr
Definition: exprtk.hpp:10671
expression_node< T >::node_type type() const
Definition: exprtk.hpp:11299
str_base_ptr str_base_ptr_
Definition: exprtk.hpp:7841
static control_block * create()
Definition: exprtk.hpp:16674
Definition: exprtk.hpp:9324
Definition: exprtk.hpp:4908
Definition: exprtk.hpp:16197
expression_node_ptr synthesize_assignment_expression(const details::operator_type &operation, expression_node_ptr(&branch)[2])
Definition: exprtk.hpp:27561
T2 t2_
Definition: exprtk.hpp:14114
vector_holder_t & vec_holder()
Definition: exprtk.hpp:7057
bool final_stmt_return_
Definition: exprtk.hpp:19214
expression_ptr index_
Definition: exprtk.hpp:7120
symbol_table_t::variable_ptr variable_ptr
Definition: exprtk.hpp:18550
bfunc_t f0() const
Definition: exprtk.hpp:13806
expression_node_ptr varnode_optimise_sf4(const details::operator_type &operation, expression_node_ptr(&branch)[4])
Definition: exprtk.hpp:26975
parser< T > & parser_
Definition: exprtk.hpp:20805
expression_ptr test_
Definition: exprtk.hpp:6082
const T & v_
Definition: exprtk.hpp:14482
static expression_node_ptr process(expression_generator< Type > &expr_gen, const details::operator_type &operation, expression_node_ptr(&branch)[2])
Definition: exprtk.hpp:32487
Definition: exprtk.hpp:4148
results_context< T > results_context_t
Definition: exprtk.hpp:18221
Definition: exprtk.hpp:12490
bool initialised_
Definition: exprtk.hpp:8433
generic_function_node(const std::vector< expression_ptr > &arg_list, GenericFunction *func=(GenericFunction *)(0))
Definition: exprtk.hpp:11428
generic_type::scalar_view scalar_t
Definition: exprtk.hpp:37882
std::string inequality_opr_to_string(details::operator_type opr)
Definition: exprtk.hpp:19773
Definition: exprtk.hpp:6101
Definition: exprtk.hpp:4922
Definition: exprtk.hpp:4405
virtual ~unknown_symbol_resolver()
Definition: exprtk.hpp:19019
println< T > pl
Definition: exprtk.hpp:36559
vocovov_t::sf4_type sf4_type
Definition: exprtk.hpp:33287
generic_type::vector_view vector_t
Definition: exprtk.hpp:37154
details::functor_t< T > functor_t
Definition: exprtk.hpp:13761
func_2param()
Definition: exprtk.hpp:35755
expression_node< T >::node_type type() const
Definition: exprtk.hpp:11883
T sgn_impl(const T v, real_type_tag)
Definition: exprtk.hpp:1084
T process(const operator_type operation, const T arg0, const T arg1)
Definition: exprtk.hpp:4886
void update(const T &v0, const T &v1, const T &v2, const T &v3, const T &v4, const T &v5)
Definition: exprtk.hpp:35544
Definition: exprtk.hpp:4409
Definition: exprtk.hpp:19259
Definition: exprtk.hpp:2026
Definition: exprtk.hpp:16104
operator_joiner(const std::size_t &stride)
Definition: exprtk.hpp:3236
operator_type operation() const
Definition: exprtk.hpp:14678
break_exception(const T &v)
Definition: exprtk.hpp:6094
Definition: exprtk.hpp:13617
std::vector< lexer::token_joiner * > token_joiner_list
Definition: exprtk.hpp:3939
file_mode mode
Definition: exprtk.hpp:36608
bool resolve_unknown_symbol_
Definition: exprtk.hpp:34660
T asinh_impl(const T v, real_type_tag)
Definition: exprtk.hpp:1286
expression_node< T >::node_type type() const
Definition: exprtk.hpp:14415
static expression_node_ptr process(expression_generator< Type > &expr_gen, const details::operator_type &operation, expression_node_ptr(&branch)[2])
Definition: exprtk.hpp:31647
expression_node< T > * expression_ptr
Definition: exprtk.hpp:7346
static T process(const T &t0, const T &t1, const T &t2, const T &t3, const bfunc_t bf0, const bfunc_t bf1, const bfunc_t bf2)
Definition: exprtk.hpp:13511
std::size_t get_stringvar_list(Sequence< std::string, Allocator > &svlist) const
Definition: exprtk.hpp:17290
Definition: exprtk.hpp:13452
expression_node_ptr switch_statement(Sequence< expression_node_ptr, Allocator > &arg_list)
Definition: exprtk.hpp:26692
static const double pi_4
Definition: exprtk.hpp:741
bool all_nodes_variables(expression_node< T > *(&b)[N])
Definition: exprtk.hpp:5167
char_cptr base() const
Definition: exprtk.hpp:11658
vovocov_t::type4 node_type
Definition: exprtk.hpp:33230
virtual vector_node_ptr vec() const =0
void clear_errors()
Definition: exprtk.hpp:3542
T hypot_impl(const T v0, const T v1, real_type_tag)
Definition: exprtk.hpp:1036
expression_node< typename node_type::value_type > * allocate_rr(T1 &t1, T2 &t2) const
Definition: exprtk.hpp:15496
const T value_
Definition: exprtk.hpp:5538
std::size_t error_count() const
Definition: exprtk.hpp:3679
int upper_bound
Definition: exprtk.hpp:4521
expression_node< T > * expression_ptr
Definition: exprtk.hpp:7243
#define register_op(Symbol, Type, Args)
Definition: exprtk.hpp:37474
#define exprtk_register_complex_type_tag(T)
Definition: exprtk.hpp:768
Definition: exprtk.hpp:4405
static std::string id()
Definition: exprtk.hpp:13603
bool binext_optimisable(const details::operator_type &operation, expression_node_ptr(&branch)[2]) const
Definition: exprtk.hpp:25963
const local_data_t & local_data() const
Definition: exprtk.hpp:17543
void clear_strings()
Definition: exprtk.hpp:16750
Definition: exprtk.hpp:4439
Definition: exprtk.hpp:4430
expression_node< T > * expression_ptr
Definition: exprtk.hpp:8331
copy< T > cp
Definition: exprtk.hpp:38172
static std::string id(expression_generator< Type > &expr_gen, const details::operator_type o0, const details::operator_type o1)
Definition: exprtk.hpp:30002
bool sf3_optimisable(const std::string &sf3id, trinary_functor_t &tfunc)
Definition: exprtk.hpp:25647
bool arithmetic_enabled(const details::operator_type &arithmetic_operation)
Definition: exprtk.hpp:19463
static T process_1(const Sequence &arg_list)
Definition: exprtk.hpp:12385
void scan_number()
Definition: exprtk.hpp:2593
Definition: exprtk.hpp:11992
SType0 s0_
Definition: exprtk.hpp:15122
range_pack< T > range_t
Definition: exprtk.hpp:11421
T process_impl(const operator_type operation, const T arg)
Definition: exprtk.hpp:4750
expression_node_ptr synthesize_uvouv_expression(const details::operator_type &operation, expression_node_ptr(&branch)[2])
Definition: exprtk.hpp:33583
bool result()
Definition: exprtk.hpp:3416
std::size_t symbols(Sequence< symbol_t, Allocator > &symbols_list)
Definition: exprtk.hpp:19084
details::while_loop_bc_node< T > while_loop_bc_node_t
Definition: exprtk.hpp:18141
type_store< igeneric_function< T >, igeneric_function< T > > generic_function_store
Definition: exprtk.hpp:16609
symbol_table_t::vector_holder_ptr vector_holder_ptr
Definition: exprtk.hpp:18555
std::size_t & max_num_args()
Definition: exprtk.hpp:15780
details::T0oT1oT2oT3_define< T, cref_t, const_t, const_t, cref_t > vococov_t
Definition: exprtk.hpp:18219
results_context_t * results
Definition: exprtk.hpp:17678
static details::operator_type operation()
Definition: exprtk.hpp:12200
std::string & s2()
Definition: exprtk.hpp:15115
Definition: exprtk.hpp:13443
T acosh_impl(const T v, real_type_tag)
Definition: exprtk.hpp:1284
Definition: exprtk.hpp:19260
SType1 s1_
Definition: exprtk.hpp:14881
static expression_node< T > * allocate(Allocator &allocator, T0 p0, T1 p1, T2 p2, T3 p3)
Definition: exprtk.hpp:14284
Definition: exprtk.hpp:4914
T hypot_impl(const T v0, const T v1, int_type_tag)
Definition: exprtk.hpp:1042
eof< T > e
Definition: exprtk.hpp:37050
static expression_node< T >::node_type type()
Definition: exprtk.hpp:11999
vds_t vds_
Definition: exprtk.hpp:9899
Definition: exprtk.hpp:565
static T process(const arg_list_t &arg)
Definition: exprtk.hpp:26652
data_ptr_t data_
Definition: exprtk.hpp:4123
expression_node< T > * expression_ptr
Definition: exprtk.hpp:7193
bool is_t0ot1ot2ot3_node(const expression_node< T > *node)
Definition: exprtk.hpp:15304
static T_ execute(ifunction &f, T_(&v)[7])
Definition: exprtk.hpp:11253
SType1 s1_
Definition: exprtk.hpp:14756
unary_vector_node(const operator_type &opr, expression_ptr branch0)
Definition: exprtk.hpp:10829
Definition: exprtk.hpp:3791
bool is_break_node(const expression_node< T > *node)
Definition: exprtk.hpp:5093
Operation operation_t
Definition: exprtk.hpp:15081
Definition: exprtk.hpp:14592
range_pack< T > range_t
Definition: exprtk.hpp:8859
void init_synthesize_map()
Definition: exprtk.hpp:25446
unary_branch_node< T, Operation > & operator=(unary_branch_node< T, Operation > &)
std::size_t function_count() const
Definition: exprtk.hpp:16795
Definition: exprtk.hpp:4419
static void process(const std::string &scalar_format, parameter_list_t parameters)
Definition: exprtk.hpp:36464
Definition: exprtk.hpp:4449
std::size_t size() const
Definition: exprtk.hpp:4100
void enable_unknown_symbol_resolver(unknown_symbol_resolver *usr=reinterpret_cast< unknown_symbol_resolver * >(0))
Definition: exprtk.hpp:20199
~trinary_node()
Definition: exprtk.hpp:5902
static T result(T)
Definition: exprtk.hpp:1564
operator_type operation() const
Definition: exprtk.hpp:13781
static expression_node_ptr process(expression_generator< Type > &expr_gen, const details::operator_type &operation, expression_node_ptr(&branch)[2])
Definition: exprtk.hpp:32954
Definition: exprtk.hpp:13571
static const std::size_t pow10_size
Definition: exprtk.hpp:732
Definition: exprtk.hpp:4893
expression_node_ptr parse_conditional_statement_02(expression_node_ptr condition)
Definition: exprtk.hpp:21241
expression_ptr test_
Definition: exprtk.hpp:6030
~control_block()
Definition: exprtk.hpp:16666
range_t * range_ptr
Definition: exprtk.hpp:8860
expression< T >::symtab_list_t symbol_table_list_t
Definition: exprtk.hpp:18176
details::T0oT1oT2oT3_define< T, cref_t, const_t, cref_t, const_t > vocovoc_t
Definition: exprtk.hpp:18217
details::vector_node< T > vector_node_t
Definition: exprtk.hpp:18150
static T process(Type t1, Type t2)
Definition: exprtk.hpp:12093
lexer::token error_token()
Definition: exprtk.hpp:3432
stringvar_node< T > * strvar_node_ptr
Definition: exprtk.hpp:7727
vector_holder_ptr vector_holder_
Definition: exprtk.hpp:7234
bool remove_replace_symbol(const std::string &symbol)
Definition: exprtk.hpp:20189
bool is_comment_start(details::char_cptr itr)
Definition: exprtk.hpp:2338
bool & allow_zero_parameters()
Definition: exprtk.hpp:15765
details::operator_type operator_t
Definition: exprtk.hpp:18185
sosos_node(SType0 p0, SType1 p1, SType2 p2)
Definition: exprtk.hpp:15084
range_t range() const
Definition: exprtk.hpp:7613
range_ptr str0_range_ptr_
Definition: exprtk.hpp:15071
bool & has_side_effects()
Definition: exprtk.hpp:15770
exprtk::igeneric_function< T > igfun_t
Definition: exprtk.hpp:37638
igfun_t::generic_type generic_type
Definition: exprtk.hpp:37432
static std::string id(expression_generator< Type > &expr_gen, const details::operator_type o0, const details::operator_type o1)
Definition: exprtk.hpp:30361
Definition: exprtk.hpp:4411
virtual ~vob_base_node()
Definition: exprtk.hpp:13152
Definition: exprtk.hpp:4164
~multi_switch_node()
Definition: exprtk.hpp:6716
vec_data_store< T > vds_t
Definition: exprtk.hpp:6981
T1 t1_
Definition: exprtk.hpp:14214
std::size_t index
Definition: exprtk.hpp:18299
Definition: exprtk.hpp:35709
static T process_4(const Sequence &arg_list)
Definition: exprtk.hpp:12280
const bool loop_body_deletable_
Definition: exprtk.hpp:6265
Definition: exprtk.hpp:4457
range_pack< T > range_t
Definition: exprtk.hpp:14973
expression_node_ptr parse_function_call_0(ifunction< T > *function, const std::string &function_name)
Definition: exprtk.hpp:20981
const token_t & current_token() const
Definition: exprtk.hpp:3997
freefunc00(ff00_functor ff)
Definition: exprtk.hpp:16027
Definition: exprtk.hpp:4921
Definition: exprtk.hpp:19305
Definition: exprtk.hpp:13316
expression(const expression< T > &e)
Definition: exprtk.hpp:17693
expression_node< T >::node_type type() const
Definition: exprtk.hpp:5808
std::pair< expression_ptr, bool > branch_t
Definition: exprtk.hpp:15236
exprtk::igeneric_function< T > igfun_t
Definition: exprtk.hpp:38076
static void destroy(st_data *&sd)
Definition: exprtk.hpp:16644
T cos_impl(const T v, real_type_tag)
Definition: exprtk.hpp:1290
static T evaluate(const Type x, const Type c12, const Type c11, const Type c10, const Type c9, const Type c8, const Type c7, const Type c6, const Type c5, const Type c4, const Type c3, const Type c2, const Type c1, const Type c0)
Definition: exprtk.hpp:35160
details::stringvar_node< T > stringvar_t
Definition: exprtk.hpp:16586
expression_node< T >::node_type type() const
Definition: exprtk.hpp:7553
Definition: exprtk.hpp:18545
T operator()(const std::size_t &ps_index, parameter_list_t parameters)
Definition: exprtk.hpp:37259
Definition: exprtk.hpp:4922
bool final_stmt_return() const
Definition: exprtk.hpp:19157
Definition: exprtk.hpp:19222
Definition: exprtk.hpp:35400
expression_node< T >::node_type type() const
Definition: exprtk.hpp:13292
const bool v_deletable_
Definition: exprtk.hpp:9477
Definition: exprtk.hpp:12004
T value() const
Definition: exprtk.hpp:9613
Definition: exprtk.hpp:11157
Definition: exprtk.hpp:7127
expression_node_ptr return_call(std::vector< expression_node_ptr > &arg_list)
Definition: exprtk.hpp:27363
Definition: exprtk.hpp:4911
void clear(const bool delete_node=true)
Definition: exprtk.hpp:16504
expression_node< T > * expression_ptr
Definition: exprtk.hpp:9599
string_base_node< T > * str_base_ptr
Definition: exprtk.hpp:8582
range_pack< T > range_t
Definition: exprtk.hpp:7574
static std::string id(expression_generator< Type > &expr_gen, const details::operator_type o0, const details::operator_type o1)
Definition: exprtk.hpp:29708
vovov_t::type0 node_type
Definition: exprtk.hpp:29416
Definition: exprtk.hpp:4437
expression_node< T > * expression_ptr
Definition: exprtk.hpp:14451
void set_ibom(inv_binary_op_map_t &inv_binary_op_map)
Definition: exprtk.hpp:25534
details::T0oT1oT2_define< T, cref_t, const_t, const_t > vococ_t
Definition: exprtk.hpp:18208
vector_node< T > * vec_node_ptr_
Definition: exprtk.hpp:9745
bool valid_symbol(const std::string &symbol) const
Definition: exprtk.hpp:18583
Definition: exprtk.hpp:4458
Definition: exprtk.hpp:4459
expression_node< T >::node_type type() const
Definition: exprtk.hpp:6156
vector_node< T > * vector_node_ptr
Definition: exprtk.hpp:10180
std::deque< std::string > v_
Definition: exprtk.hpp:35488
Definition: exprtk.hpp:36455
Definition: exprtk.hpp:3490
Definition: exprtk.hpp:4414
expression_node< typename node_type::value_type > * allocate(const T1 &t1, const T2 &t2, const T3 &t3, const T4 &t4, const T5 &t5, const T6 &t6, const T7 &t7, const T8 &t8, const T9 &t9, const T10 &t10) const
Definition: exprtk.hpp:15625
Definition: exprtk.hpp:5835
Definition: exprtk.hpp:4448
void copy(const varref_t &src_v, var_t &dest_v)
Definition: exprtk.hpp:35631
#define register_synthezier(S)
scoped_bool_or_restorer(bool &bb)
Definition: exprtk.hpp:20827
opr_base< T >::Type Type
Definition: exprtk.hpp:11994
std::vector< expression_ptr > arg_list_
Definition: exprtk.hpp:8979
Definition: exprtk.hpp:4424
static T process_4(const Sequence &arg_list)
Definition: exprtk.hpp:12543
expression_node_ptr synthesize_csosr_expression(const details::operator_type &opr, expression_node_ptr(&branch)[2])
Definition: exprtk.hpp:33822
operator_type operation() const
Definition: exprtk.hpp:14517
expression_node_ptr generic_function_call(igeneric_function_t *gf, std::vector< expression_node_ptr > &arg_list, const std::size_t &param_seq_index=std::numeric_limits< std::size_t >::max())
Definition: exprtk.hpp:27253
Definition: exprtk.hpp:4451
static T process_2(const Sequence &arg_list)
Definition: exprtk.hpp:12760
ivararg_function< T > vararg_function_t
Definition: exprtk.hpp:16590
Definition: exprtk.hpp:4453
virtual operator_type operation() const
Definition: exprtk.hpp:13177
static T process(const T &t0, const T &t1, const T &t2, const bfunc_t bf0, const bfunc_t bf1)
Definition: exprtk.hpp:13486
Definition: exprtk.hpp:4395
virtual bool modify(token &t)=0
range_interface< T > range_interface_t
Definition: exprtk.hpp:11419
std::size_t process(generator &g)
Definition: exprtk.hpp:2973
State start
Definition: x.cpp:24
generic_type::scalar_view scalar_t
Definition: exprtk.hpp:37930
void swap(::possumwood::io::json &j1,::possumwood::io::json &j2) noexcept(is_nothrow_move_constructible<::possumwood::io::json >::value andis_nothrow_move_assignable<::possumwood::io::json >::value)
exchanges the values of two JSON objects
Definition: json.h:14378
store_type type
Definition: exprtk.hpp:4162
static void execute(T_(&v)[3], const branch_t(&b)[3])
Definition: exprtk.hpp:11129
Definition: exprtk.hpp:4414
expression_node_ptr cardinal_pow_optimisation_impl(const TType &v, const unsigned int &p)
Definition: exprtk.hpp:28036
virtual std::size_t vector_size() const =0
bool string_to_real(Iterator &itr_external, const Iterator end, T &t, numeric::details::real_type_tag)
Definition: exprtk.hpp:1820
T(* ufunc_t)(Type t0)
Definition: exprtk.hpp:2006
const Type * vec_
Definition: exprtk.hpp:5313
static T_ execute(ifunction &f, T_(&v)[2])
Definition: exprtk.hpp:11288
std::string arith_opr_to_string(details::operator_type opr)
Definition: exprtk.hpp:19760
vovocov_t::sf4_type sf4_type
Definition: exprtk.hpp:33231
value_t & operator[](const std::size_t &i)
Definition: exprtk.hpp:4240
expression_node_ptr parse_string_range_statement(expression_node_ptr &expression)
Definition: exprtk.hpp:22366
expression_node< typename node_type::value_type > * allocate(const T1 &t1, const T2 &t2, const T3 &t3, const T4 &t4, const T5 &t5, const T6 &t6, const T7 &t7) const
Definition: exprtk.hpp:15584
bool is_voc_node(const expression_node< T > *node)
Definition: exprtk.hpp:15280
type_store< T > type_store_t
Definition: exprtk.hpp:11413
opr_base< T >::Type Type
Definition: exprtk.hpp:12186
static expression_node< T >::node_type type()
Definition: exprtk.hpp:12065
details::functor_t< T >::Type Type
Definition: exprtk.hpp:9001
bool is_hex_digit(const std::string::value_type digit)
Definition: exprtk.hpp:295
parser_state state_
Definition: exprtk.hpp:34659
type_t * type_ptr
Definition: exprtk.hpp:16210
expression_node< T >::node_type type() const
Definition: exprtk.hpp:8559
Definition: exprtk.hpp:19255
expression_node< typename ResultNode::value_type > * allocate(OpType &operation, ExprNode(&branch)[2])
Definition: exprtk.hpp:15417
virtual void set_ref(value_ptr *)
Definition: exprtk.hpp:5277
bool open()
Definition: exprtk.hpp:36611
bool * return_invoked
Definition: exprtk.hpp:17680
std::string str() const
Definition: exprtk.hpp:7945
static T_ execute(ifunction &f, T_(&v)[16])
Definition: exprtk.hpp:11190
static void execute(std::string &s, char_cptr data, const std::size_t size)
Definition: exprtk.hpp:8314
char_cptr base() const
Definition: exprtk.hpp:7603
T operator()(const std::size_t &ps_index, parameter_list_t parameters)
Definition: exprtk.hpp:37805
std::string paramseq(const std::size_t &index) const
Definition: exprtk.hpp:23211
covov_t::type1 node_type
Definition: exprtk.hpp:29837
stringvar_ptr get_stringvar(const std::string &string_name) const
Definition: exprtk.hpp:18639
std::size_t size() const
Definition: exprtk.hpp:10947
settings_store & disable_arithmetic_operation(settings_arithmetic_opr arithmetic)
Definition: exprtk.hpp:19580
virtual const T & v() const =0
Definition: exprtk.hpp:4434
void disable_type_checking(Parser &p)
Definition: exprtk.hpp:18091
vds_t & vds()
Definition: exprtk.hpp:10645
details::T0oT1oT2_define< T, cref_t, cref_t, cref_t > vovov_t
Definition: exprtk.hpp:18202
bool bov_optimisable(const details::operator_type &operation, expression_node_ptr(&branch)[2]) const
Definition: exprtk.hpp:25954
RangePack rp1_
Definition: exprtk.hpp:14958
static T process(const ivector_ptr v)
Definition: exprtk.hpp:12936
Definition: exprtk.hpp:3232
Definition: exprtk.hpp:4920
expression_ptr loop_body_
Definition: exprtk.hpp:6210
expression_node< T > * expression_ptr
Definition: exprtk.hpp:15138
igfun_t::generic_type generic_type
Definition: exprtk.hpp:37245
axpby< T > b1_axpby
Definition: exprtk.hpp:38182
expression_node_ptr vector_element(const std::string &symbol, vector_holder_ptr vector_base, expression_node_ptr index)
Definition: exprtk.hpp:27420
bool coboc_optimisable(const details::operator_type &operation, expression_node_ptr(&branch)[2]) const
Definition: exprtk.hpp:25920
Definition: exprtk.hpp:4425
Definition: exprtk.hpp:11019
static expression_node_ptr process(expression_generator< Type > &expr_gen, const details::operator_type &operation, expression_node_ptr(&branch)[2])
Definition: exprtk.hpp:33348
symbol_table_t::generic_function_ptr generic_function_ptr
Definition: exprtk.hpp:18557
Definition: exprtk.hpp:4458
void free(expression_node< T > *&e) const
Definition: exprtk.hpp:15685
Definition: exprtk.hpp:4393
bool enable_commutative_check_
Definition: exprtk.hpp:19794
Definition: exprtk.hpp:6105
const bfunc_t f1_
Definition: exprtk.hpp:13843
expression_node< typename node_type::value_type > * allocate_ttt(T1 t1, T2 t2, T3 t3) const
Definition: exprtk.hpp:15510
lexer::helper::operator_joiner operator_joiner_2_
Definition: exprtk.hpp:34676
static std::string id()
Definition: exprtk.hpp:14003
parser< T > & parser_
Definition: exprtk.hpp:20772
parser< T > parser_t
Definition: exprtk.hpp:18512
expression_node_ptr synthesize_shortcircuit_expression(const details::operator_type &operation, expression_node_ptr(&branch)[2])
Definition: exprtk.hpp:27955
generic_type::scalar_view scalar_t
Definition: exprtk.hpp:37835
Definition: exprtk.hpp:12110
static T_ execute(ifunction &f, T_(&v)[19])
Definition: exprtk.hpp:11169
bool is_ivariable_node(const expression_node< T > *node)
Definition: exprtk.hpp:5021
vovovov_t::type3 node_type
Definition: exprtk.hpp:32610
static expression_node_ptr process(expression_generator< Type > &expr_gen, const details::operator_type &sf3opr, T0 t0, T1 t1, T2 t2)
Definition: exprtk.hpp:29178
static bool compile_left_impl(expression_generator< Type > &expr_gen, const std::string &id, ExternalType t, expression_node_ptr &node, expression_node_ptr &result)
Definition: exprtk.hpp:29392
Definition: exprtk.hpp:4443
details::T0oT1oT2oT3_define< T, cref_t, cref_t, cref_t, cref_t > vovovov_t
Definition: exprtk.hpp:18210
Definition: exprtk.hpp:12296
static void match_sizes(type &vds0, type &vds1)
Definition: exprtk.hpp:4722
vovovov_t::type4 node_type
Definition: exprtk.hpp:33117
static expression_node_ptr process(expression_generator< Type > &expr_gen, const details::operator_type &operation, expression_node_ptr(&branch)[2])
Definition: exprtk.hpp:33068
Definition: exprtk.hpp:14347
details::cons_conditional_node< T > cons_conditional_node_t
Definition: exprtk.hpp:18136
assignment_rebasevec_elem_op_node(const operator_type &opr, expression_ptr branch0, expression_ptr branch1)
Definition: exprtk.hpp:9983
T value() const
Definition: exprtk.hpp:9800
Definition: exprtk.hpp:4436
Definition: exprtk.hpp:4427
lexer::token error_token_
Definition: exprtk.hpp:3487
std::size_t ref_count
Definition: exprtk.hpp:16699
void init_branches(std::pair< expression_node< T > *, bool >(&branch)[N], expression_node< T > *b0, expression_node< T > *b1=reinterpret_cast< expression_node< T > * >(0), expression_node< T > *b2=reinterpret_cast< expression_node< T > * >(0), expression_node< T > *b3=reinterpret_cast< expression_node< T > * >(0), expression_node< T > *b4=reinterpret_cast< expression_node< T > * >(0), expression_node< T > *b5=reinterpret_cast< expression_node< T > * >(0), expression_node< T > *b6=reinterpret_cast< expression_node< T > * >(0), expression_node< T > *b7=reinterpret_cast< expression_node< T > * >(0), expression_node< T > *b8=reinterpret_cast< expression_node< T > * >(0), expression_node< T > *b9=reinterpret_cast< expression_node< T > * >(0))
Definition: exprtk.hpp:5726
Definition: exprtk.hpp:4454
T operator()(const std::size_t &ps_index, parameter_list_t parameters)
Definition: exprtk.hpp:36904
static T process(const T &, const T &)
Definition: exprtk.hpp:12177
Definition: exprtk.hpp:4919
expression_node< T > * expression_ptr
Definition: exprtk.hpp:14971
SType1 s1_
Definition: exprtk.hpp:14956
T value() const
Definition: exprtk.hpp:7420
variable_node()
Definition: exprtk.hpp:6783
static T process_4(const Sequence &arg_list)
Definition: exprtk.hpp:12697
Definition: exprtk.hpp:4449
static T evaluate(const Type x, const Type c5, const Type c4, const Type c3, const Type c2, const Type c1, const Type c0)
Definition: exprtk.hpp:35247
details::stringvar_node< T > stringvar_node_t
Definition: exprtk.hpp:16206
token & set_error(const token_type et, const Iterator begin, const Iterator end, const Iterator base_begin=Iterator(0))
Definition: exprtk.hpp:2097
std::vector< expression_ptr > arg_list_
Definition: exprtk.hpp:6660
const range_t & range_ref() const
Definition: exprtk.hpp:7633
details::T0oT1_define< T, cref_t, const_t > voc_t
Definition: exprtk.hpp:18200
bool remove_function(const std::string &function_name)
Definition: exprtk.hpp:17201
Definition: exprtk.hpp:4902
virtual bool join(const token &, const token &, token &)
Definition: exprtk.hpp:3095
Definition: exprtk.hpp:4899
std::deque< var_t > param_stack
Definition: exprtk.hpp:35703
bool is_invalid_assignment_op(const details::operator_type &operation, expression_node_ptr(&branch)[2])
Definition: exprtk.hpp:25972
expression_node< T > * expression_ptr
Definition: exprtk.hpp:6484
ff00_functor f
Definition: exprtk.hpp:16030
expression_node_ptr synthesize_sros_expression(const details::operator_type &opr, expression_node_ptr(&branch)[2])
Definition: exprtk.hpp:33747
static std::string id(expression_generator< Type > &, const details::operator_type, const details::operator_type, const details::operator_type)
Definition: exprtk.hpp:33575
static expression_node_ptr process(expression_generator< Type > &expr_gen, const details::operator_type &operation, expression_node_ptr(&branch)[2])
Definition: exprtk.hpp:29098
const T & v1_
Definition: exprtk.hpp:13382
vec_data_store< T > vds_t
Definition: exprtk.hpp:10827
bool is_false_impl(const T v)
Definition: exprtk.hpp:849
const T & v() const
Definition: exprtk.hpp:14430
symtab_list_t get_symbol_table_list() const
Definition: exprtk.hpp:17812
unknown_symbol_resolver * unknown_symbol_resolver_
Definition: exprtk.hpp:34662
range_t * range_ptr
Definition: exprtk.hpp:14974
expression_node< T >::node_type type() const
Definition: exprtk.hpp:7451
bool delete_ptr
Definition: exprtk.hpp:20738
~bov_node()
Definition: exprtk.hpp:14557
define_sfop3(00,(x+y)/z,"(t+t)/t") define_sfop3(01
shift_right()
Definition: exprtk.hpp:37589
details::T0oT1oT2oT3_sf4< T, T0, T1, T2, T3 > sf4_type
Definition: exprtk.hpp:14343
Definition: exprtk.hpp:18108
expression_node< T > * expression_ptr
Definition: exprtk.hpp:10975
Definition: exprtk.hpp:4431
expression_ptr incrementor_
Definition: exprtk.hpp:6347
type_store< typename details::stringvar_node< T >, std::string > stringvar_store
Definition: exprtk.hpp:16605
scope_handler(parser< T > &p)
Definition: exprtk.hpp:18514
expression_node< T >::node_type type() const
Definition: exprtk.hpp:13775
std::string str() const
Definition: exprtk.hpp:7676
bool enable_strength_reduction_
Definition: exprtk.hpp:19795
::erf real_type_tag
Definition: exprtk.hpp:1195
virtual ~ivararg_function()
Definition: exprtk.hpp:15937
bool is_variable(const std::string &variable_name) const
Definition: exprtk.hpp:17334
Definition: exprtk.hpp:4428
std::size_t size() const
Definition: exprtk.hpp:7686
generic_type::string_view string_t
Definition: exprtk.hpp:36461
all_false()
Definition: exprtk.hpp:37204
bool inequality_disabled(const details::operator_type &inequality)
Definition: exprtk.hpp:19532
T value_type
Definition: exprtk.hpp:13696
Definition: exprtk.hpp:13447
const_string_range_node(const std::string &v, const range_t &rp)
Definition: exprtk.hpp:7661
vovovoc_t::type0 node_type
Definition: exprtk.hpp:30499
settings_store & disable_assignment_operation(settings_assignment_opr assignment)
Definition: exprtk.hpp:19593
expression_node< T > * expression_ptr
Definition: exprtk.hpp:7726
T operator()(const std::size_t &ps_index, parameter_list_t parameters)
Definition: exprtk.hpp:37447
Definition: exprtk.hpp:4403
std::set< std::string, details::ilesscompare > disabled_func_set_t
Definition: exprtk.hpp:18196
bool enable_collect_funcs_
Definition: exprtk.hpp:19797
static std::pair< bool, vector_t * > make(std::vector< T, Allocator > &v, const bool is_const=false)
Definition: exprtk.hpp:16307
strvar_node_ptr str0_node_ptr_
Definition: exprtk.hpp:8569
repeat_until_loop_bc_node(expression_ptr condition, expression_ptr loop_body)
Definition: exprtk.hpp:6424
Definition: exprtk.hpp:11347
scoped_delete(parser< T > &pr, ptr_t &p)
Definition: exprtk.hpp:20715
T3 t3_
Definition: exprtk.hpp:14216
T value() const
Definition: exprtk.hpp:11816
vococov_t::type0 node_type
Definition: exprtk.hpp:31452
Definition: exprtk.hpp:37923
igeneric_function< T > generic_function_t
Definition: exprtk.hpp:16591
scalar_view(type_store_t &ts)
Definition: exprtk.hpp:4275
T value() const
Definition: exprtk.hpp:7022
const bool index_deletable_
Definition: exprtk.hpp:7182
T roundn(const T v0, const T v1)
Definition: exprtk.hpp:1447
operator_type operation() const
Definition: exprtk.hpp:14465
rebasevector_celem_node(const std::size_t index, vector_holder_ptr vec_holder)
Definition: exprtk.hpp:7198
T pow(const T v0, const T v1)
Definition: exprtk.hpp:1426
Definition: exprtk.hpp:14221
static T process_5(const Sequence &arg_list)
Definition: exprtk.hpp:12784
ifunction< T > F
Definition: exprtk.hpp:18123
uchar_t hex_to_bin(uchar_t h)
Definition: exprtk.hpp:302
virtual const T & v() const =0
bool eof()
Definition: exprtk.hpp:36741
Definition: exprtk.hpp:6764
igfun_t::generic_type generic_type
Definition: exprtk.hpp:38078
rebasevector_elem_node< T > * rbvec_node_ptr_
Definition: exprtk.hpp:9591
static const double log2
Definition: exprtk.hpp:746
igfun_t::parameter_list_t parameter_list_t
Definition: exprtk.hpp:36892
vovoc_t::type0 node_type
Definition: exprtk.hpp:29536
expression_node< T > * expression_ptr
Definition: exprtk.hpp:5984
Definition: exprtk.hpp:4401
igfun_t::parameter_list_t parameter_list_t
Definition: exprtk.hpp:37978
virtual operator_type operation() const
Definition: exprtk.hpp:13137
expression_node< T >::node_type type() const
Definition: exprtk.hpp:7638
Definition: exprtk.hpp:35724
Definition: exprtk.hpp:4909
vec_binop_vecvec_node(const operator_type &opr, expression_ptr branch0, expression_ptr branch1)
Definition: exprtk.hpp:10335
ivariable_ptr var0_
Definition: exprtk.hpp:7368
T1 t1() const
Definition: exprtk.hpp:13796
~vec_binop_vecvec_node()
Definition: exprtk.hpp:10397
bool add_package(Package &package)
Definition: exprtk.hpp:17252
static T process(Type t1, Type t2)
Definition: exprtk.hpp:12123
std::vector< T * > varref_t
Definition: exprtk.hpp:35497
operator_type operation() const
Definition: exprtk.hpp:13346
expression_t expression
Definition: exprtk.hpp:35698
std::size_t size() const
Definition: exprtk.hpp:7456
void copy(const var_t &src_v, lvr_vec_t &dest_v)
Definition: exprtk.hpp:35666
std::pair< T *, std::size_t > lvarref_t
Definition: exprtk.hpp:35499
axpbyz()
Definition: exprtk.hpp:37985
static void assign(RefType t1, Type t2)
Definition: exprtk.hpp:12044
static expression_node_ptr process(expression_generator< Type > &expr_gen, const details::operator_type &operation, expression_node_ptr(&branch)[2])
Definition: exprtk.hpp:30251
opr_base< T >::Type Type
Definition: exprtk.hpp:12563
node_type
Definition: exprtk.hpp:4897
static std::string id(expression_generator< Type > &expr_gen, const details::operator_type o0, const details::operator_type o1, const details::operator_type o2)
Definition: exprtk.hpp:32824
std::vector< expression_ptr > arg_list_
Definition: exprtk.hpp:9379
covocov_t::type2 node_type
Definition: exprtk.hpp:32423
opr_base< T >::RefType RefType
Definition: exprtk.hpp:11983
T trunc_impl(const T v, real_type_tag)
Definition: exprtk.hpp:1313
T operator()(const std::size_t &ps_index, parameter_list_t parameters)
Definition: exprtk.hpp:37756
static bool parse_inf(Iterator &itr, const Iterator end, T &t, bool negative)
Definition: exprtk.hpp:1786
details::vector_holder< T > * vector_holder_ptr
Definition: exprtk.hpp:18177
bov_node(const expression_ptr brnch, const T &var)
Definition: exprtk.hpp:14551
range_pack< T > range_t
Definition: exprtk.hpp:11608
~function_compositor()
Definition: exprtk.hpp:35911
node_type & operator=(node_type &)
Definition: exprtk.hpp:14294
Definition: exprtk.hpp:4459
SType1 s1_
Definition: exprtk.hpp:15123
expression_node< T >::node_type type() const
Definition: exprtk.hpp:10635
T value() const
Definition: exprtk.hpp:11744
vector_assignment_node< T > & operator=(const vector_assignment_node< T > &)
expression_node< T > * branch(const std::size_t &) const
Definition: exprtk.hpp:5608
string_base_node< T > * str_base_ptr
Definition: exprtk.hpp:8741
expression_node_ptr parse_generic_function_call(igeneric_function< T > *function, const std::string &function_name)
Definition: exprtk.hpp:23322
expression_node_ptr synthesize_str_xroxr_expression_impl(const details::operator_type &opr, T0 s0, T1 s1, range_t rp0, range_t rp1)
Definition: exprtk.hpp:33707
bool is_shortcircuit_expression(const details::operator_type &operation) const
Definition: exprtk.hpp:26079
vovovoc_t::type2 node_type
Definition: exprtk.hpp:32198
retparam_list_t return_param_type_list() const
Definition: exprtk.hpp:19164
sequence_t & sequence_
Definition: exprtk.hpp:5345
Definition: exprtk.hpp:2023
T value() const
Definition: exprtk.hpp:7773
details::vec_data_store< Type > vds_t
Definition: exprtk.hpp:5389
generic_type::vector_view vector_t
Definition: exprtk.hpp:38032
vds_t vds_
Definition: exprtk.hpp:7184
Definition: exprtk.hpp:4455
vocovoc_t::type0 node_type
Definition: exprtk.hpp:31024
T root_impl(const T v0, const T v1, int_type_tag)
Definition: exprtk.hpp:1006
control_block()
Definition: exprtk.hpp:17599
Definition: exprtk.hpp:4457
const local_data_t & local_data(const std::size_t &index=0) const
Definition: exprtk.hpp:18946
Definition: exprtk.hpp:2023
bool sf4_optimisable(const std::string &sf4id, details::operator_type &operation)
Definition: exprtk.hpp:25683
bool is_string_operation(const details::operator_type &operation, expression_node_ptr(&branch)[2])
Definition: exprtk.hpp:26061
bool allow_zero_parameters_
Definition: exprtk.hpp:15787
expression_ptr condition_
Definition: exprtk.hpp:6473
#define batch_eqineq_logic_case
static T process(const Sequence< Type, Allocator > &arg_list)
Definition: exprtk.hpp:12497
T value() const
Definition: exprtk.hpp:10562
generic_type::vector_view vector_t
Definition: exprtk.hpp:36460
static control_block * create(expression_ptr e)
Definition: exprtk.hpp:17654
static T process(const ivector_ptr v)
Definition: exprtk.hpp:13074
std::pair< lexer::token, lexer::token > error(const std::size_t index)
Definition: exprtk.hpp:3684
static T process(Type t1, Type t2, Type t3)
Definition: exprtk.hpp:12021
Definition: exprtk.hpp:36944
ff02_functor f
Definition: exprtk.hpp:16050
range_data_type< T > range_data_type_t
Definition: exprtk.hpp:5568
generic_type::vector_view vector_t
Definition: exprtk.hpp:37792
T value() const
Definition: exprtk.hpp:14784
str_xrox_node< T, SType0, SType1, RangePack, Operation > & operator=(str_xrox_node< T, SType0, SType1, RangePack, Operation > &)
Definition: exprtk.hpp:37577
bool process(const std::string &str)
Definition: exprtk.hpp:2212
Definition: exprtk.hpp:11980
T0oT1oT2_sf3< T, T0, T1, T2 > node_type
Definition: exprtk.hpp:13953
static expression_node< T >::node_type type()
Definition: exprtk.hpp:12124
void close(Ptr &p)
Definition: exprtk.hpp:36666
Definition: exprtk.hpp:17557
rol()
Definition: exprtk.hpp:37438
details::string_range_node< T > string_range_node_t
Definition: exprtk.hpp:18155
Definition: exprtk.hpp:10971
~unary_vector_node()
Definition: exprtk.hpp:10864
static std::string id(expression_generator< Type > &expr_gen, const details::operator_type o0, const details::operator_type o1, const details::operator_type o2)
Definition: exprtk.hpp:32299
functor_t::tfunc_t trinary_functor_t
Definition: exprtk.hpp:18181
void disable_zero_parameters(FunctionType &func)
Definition: exprtk.hpp:15805
Definition: exprtk.hpp:4407
bool add_function(const std::string &function_name, generic_function_t &function)
Definition: exprtk.hpp:17039
Definition: exprtk.hpp:4924
scoped_vec_delete(parser< T > &pr, std::vector< ptr_t > &vec)
Definition: exprtk.hpp:20785
Definition: exprtk.hpp:4443
opr_base< T >::Type Type
Definition: exprtk.hpp:12052
std::pair< expression_ptr, bool > branch_t
Definition: exprtk.hpp:5785
vector_holder< T > * vector_holder_ptr
Definition: exprtk.hpp:10332
generic_function_ptr get_string_function(const std::string &function_name) const
Definition: exprtk.hpp:16872
const bool condition_deletable_
Definition: exprtk.hpp:6350
#define string_opr_switch_statements
Definition: exprtk.hpp:33659
settings_assignment_opr
Definition: exprtk.hpp:19295
virtual std::size_t process(generator &)
Definition: exprtk.hpp:2858
expression_node< T > * expression_ptr
Definition: exprtk.hpp:13280
opr_base< T >::Type Type
Definition: exprtk.hpp:12140
T2 t2_
Definition: exprtk.hpp:14298
Definition: exprtk.hpp:12184
bool add_vector(const std::string &vector_name, std::vector< T, Allocator > &v)
Definition: exprtk.hpp:17155
Definition: exprtk.hpp:4398
array_vector_impl(const Type *vec, const std::size_t &vec_size)
Definition: exprtk.hpp:5289
details::functor_t< T > functor_t
Definition: exprtk.hpp:13694
void return_cleanup()
Definition: exprtk.hpp:34634
nthelement()
Definition: exprtk.hpp:37703
expression_node< T > * expression_ptr
Definition: exprtk.hpp:6168
Definition: exprtk.hpp:4414
ipowinv_node(const T &v)
Definition: exprtk.hpp:15208
void load_compile_options(const std::size_t compile_options)
Definition: exprtk.hpp:19729
details::functor_t< T > functor_t
Definition: exprtk.hpp:9002
bool & collect_assignments()
Definition: exprtk.hpp:19147
vector_holder_ptr temp_
Definition: exprtk.hpp:10965
T shl_impl(const T v0, const T v1, real_type_tag)
Definition: exprtk.hpp:1072
vovovoc_t::sf4_type sf4_type
Definition: exprtk.hpp:32667
expression_node_ptr synthesize_uvec_expression(const details::operator_type &operation, expression_node_ptr(&branch)[1])
Definition: exprtk.hpp:26805
operator_type operation() const
Definition: exprtk.hpp:14420
opr_base< T >::Type Type
Definition: exprtk.hpp:12231
bool initialised_
Definition: exprtk.hpp:10320
symbol_list_t symbol_name_list_
Definition: exprtk.hpp:19215
std::size_t size() const
Definition: exprtk.hpp:8544
bool valid_base_operation(const std::string &symbol)
Definition: exprtk.hpp:20222
vector_holder_t * vector_holder_
Definition: exprtk.hpp:7064
static T process(Type t1, Type t2)
Definition: exprtk.hpp:11984
range_pack< T > range_t
Definition: exprtk.hpp:5587
igfun_t::generic_type generic_type
Definition: exprtk.hpp:37337
vds_t vds_
Definition: exprtk.hpp:7065
T operator()(const std::size_t &ps_index, parameter_list_t parameters)
Definition: exprtk.hpp:37543
Definition: exprtk.hpp:37376
Definition: exprtk.hpp:4456
covocov_t::sf4_type sf4_type
Definition: exprtk.hpp:30836
static const double pi_2
Definition: exprtk.hpp:740
string_base_node< T > * str_base_ptr
Definition: exprtk.hpp:8449
Definition: exprtk.hpp:7987
bool modify(lexer::token &t)
Definition: exprtk.hpp:3596
Definition: exprtk.hpp:4064
control_block::st_data local_data_t
Definition: exprtk.hpp:17536
const T c_
Definition: exprtk.hpp:14437
details::assignment_vecvec_node< T > assignment_vecvec_node_t
Definition: exprtk.hpp:18169
static bool is_constant(const expression< T > &expr)
Definition: exprtk.hpp:17928
expression_node< T > * expression_ptr
Definition: exprtk.hpp:4939
const std::string value_
Definition: exprtk.hpp:7715
T third_derivative(const expression< T > &e, T &x, const T &h=T(0.0001))
Definition: exprtk.hpp:34929
T value() const
Definition: exprtk.hpp:11529
~unary_node()
Definition: exprtk.hpp:5662
long long int to_int64_impl(const T v, real_type_tag)
Definition: exprtk.hpp:837
static const char * version
Definition: exprtk.hpp:38239
bool peek_token_is(const std::string &s)
Definition: exprtk.hpp:4050
unknown_type_tag type
Definition: exprtk.hpp:760
virtual ~helper_interface()
Definition: exprtk.hpp:2859
Definition: exprtk.hpp:37634
vector_node< T > vector_node_t
Definition: exprtk.hpp:11416
Definition: exprtk.hpp:4404
bool is_integer_impl(const T &v, real_type_tag)
Definition: exprtk.hpp:1349
T & variable_ref(const std::string &symbol_name)
Definition: exprtk.hpp:16894
T shl(const T v0, const T v1)
Definition: exprtk.hpp:1475
Definition: exprtk.hpp:25435
std::vector< range_data_type_t > range_list_t
Definition: exprtk.hpp:11426
bool is_constant_node(const expression_node< T > *node)
Definition: exprtk.hpp:5081
std::size_t size() const
Definition: exprtk.hpp:8411
Definition: exprtk.hpp:12641
expression_node< typename node_type::value_type > * allocate(const T1 &t1, const T2 &t2, const T3 &t3, const T4 &t4, const T5 &t5, const T6 &t6) const
Definition: exprtk.hpp:15573
Definition: exprtk.hpp:35751
expression_node< typename node_type::value_type > * allocate(const T1 &t1, const T2 &t2, const T3 &t3, const T4 &t4, const T5 &t5, const T6 &t6, const T7 &t7, const T8 &t8, const T9 &t9) const
Definition: exprtk.hpp:15610
Definition: exprtk.hpp:4441
static T process_5(const Sequence &arg_list)
Definition: exprtk.hpp:12410
void reset()
Definition: exprtk.hpp:3437
Definition: exprtk.hpp:4449
count()
Definition: exprtk.hpp:37342
disabled_entity_set_t::iterator des_itr_t
Definition: exprtk.hpp:19227
parser< T > parser_t
Definition: exprtk.hpp:18319
Definition: exprtk.hpp:4456
token_advance_mode
Definition: exprtk.hpp:4002
variable_node_t * variable_node_ptr
Definition: exprtk.hpp:18318
static T process_5(const Sequence &arg_list)
Definition: exprtk.hpp:12551
static expression_node_ptr process(expression_generator< Type > &expr_gen, const details::operator_type &operation, expression_node_ptr(&branch)[2])
Definition: exprtk.hpp:28128
static expression_node_ptr process(expression_generator< Type > &expr_gen, const details::operator_type &operation, expression_node_ptr(&branch)[2])
Definition: exprtk.hpp:29539
~vec_binop_valvec_node()
Definition: exprtk.hpp:10711
type_store< T > type_store_t
Definition: exprtk.hpp:4222
vovovov_t::sf4_type sf4_type
Definition: exprtk.hpp:30383
details::const_string_range_node< T > const_string_range_node_t
Definition: exprtk.hpp:18156
T1 t1_
Definition: exprtk.hpp:14297
vectorize_node(const expression_ptr v)
Definition: exprtk.hpp:9436
std::pair< bool, std::size_t > n0_c
Definition: exprtk.hpp:6944
std::size_t input_param_cnt_
Definition: exprtk.hpp:18505
string_base_node< T > * str_base_ptr
Definition: exprtk.hpp:8858
expression_ptr initialiser_
Definition: exprtk.hpp:6575
expression_ptr consequent_
Definition: exprtk.hpp:6031
opr_base< T >::Type Type
Definition: exprtk.hpp:12030
Definition: exprtk.hpp:4440
const bfunc_t f_
Definition: exprtk.hpp:13753
bool symbol_used(const std::string &symbol) const
Definition: exprtk.hpp:36051
expression_node< typename ResultNode::value_type > * allocate(OpType &operation, ExprNode(&branch)[6])
Definition: exprtk.hpp:15441
range_pack< T > range_t
Definition: exprtk.hpp:7659
std::string scalar_format_
Definition: exprtk.hpp:36552
static expression_node_ptr process(expression_generator< Type > &expr_gen, const details::operator_type &operation, expression_node_ptr(&branch)[2])
Definition: exprtk.hpp:30014
void free_node(NodeAllocator &node_allocator, expression_node< T > *&node, const bool force_delete=false)
Definition: exprtk.hpp:5220
T nand_opr(const T v0, const T v1)
Definition: exprtk.hpp:1489
expression_node< T > * expression_ptr
Definition: exprtk.hpp:8447
vector_node_ptr vec()
Definition: exprtk.hpp:10937
vovovov_t::type1 node_type
Definition: exprtk.hpp:31640
T & operator[](const std::size_t index)
Definition: exprtk.hpp:4110
const bool loop_body_deletable_
Definition: exprtk.hpp:6476
uchar_t * uchar_ptr
Definition: exprtk.hpp:88
Definition: exprtk.hpp:37875
void set_c(const T new_c)
Definition: exprtk.hpp:14688
irange_t * irange_ptr
Definition: exprtk.hpp:8745
irange_ptr str_range_ptr_
Definition: exprtk.hpp:8978
T xnor_impl(const T v0, const T v1, int_type_tag)
Definition: exprtk.hpp:1172
expression_node< T > * expression_ptr
Definition: exprtk.hpp:8581
Definition: exprtk.hpp:2028
Definition: exprtk.hpp:16063
Definition: exprtk.hpp:15231
opr_base< T >::RefType RefType
Definition: exprtk.hpp:12031
const qfunc_t f_
Definition: exprtk.hpp:14217
type_store< vector_holder_t, vector_holder_t > vector_store
Definition: exprtk.hpp:16611
Definition: exprtk.hpp:4441
void free()
Definition: exprtk.hpp:6847
std::size_t size() const
Definition: exprtk.hpp:8698
std::string as_string() const
Definition: exprtk.hpp:407
token_t operator[](const std::size_t &index) const
Definition: exprtk.hpp:2286
vector_node< T > * vec0_node_ptr_
Definition: exprtk.hpp:7473
bool sequence_match(const std::string &pattern, const std::string &str, std::size_t &diff_index, char_t &diff_value)
Definition: exprtk.hpp:654
expression_node< T > * expression_ptr
Definition: exprtk.hpp:9944
igfun_t::parameter_list_t parameter_list_t
Definition: exprtk.hpp:37928
bool result()
Definition: exprtk.hpp:3501
vector_node(vector_holder_t *vh)
Definition: exprtk.hpp:7010
parser_t::settings_store settings_t
Definition: exprtk.hpp:35398
T0oT1oT2_sf3(node_type &)
Definition: exprtk.hpp:14018
std::size_t get_list(Sequence< std::string, Allocator > &vlist) const
Definition: exprtk.hpp:16560
expression_node_ptr parse_multi_switch_statement()
Definition: exprtk.hpp:22170
expression_node< T >::node_type type() const
Definition: exprtk.hpp:14933
expression_node< T > * expression_ptr
Definition: exprtk.hpp:10999
std::size_t size() const
Definition: exprtk.hpp:7042
igeneric_function< T >::generic_type generic_type
Definition: exprtk.hpp:36457
T * vector_base_
Definition: exprtk.hpp:7122
covocov_t::sf4_type sf4_type
Definition: exprtk.hpp:31918
static T return_value(expression_t &e)
Definition: exprtk.hpp:35821
variable_node_t * variable_node_ptr_t
Definition: exprtk.hpp:11417
Definition: exprtk.hpp:4401
static const double _180_pi
Definition: exprtk.hpp:745
static details::operator_type operation()
Definition: exprtk.hpp:12152
Definition: exprtk.hpp:20386
bool is_function(const std::string &function_name) const
Definition: exprtk.hpp:18871
char_cptr base() const
Definition: exprtk.hpp:7523
Definition: exprtk.hpp:4542
Definition: exprtk.hpp:8999
assignment_rebasevec_celem_node(const operator_type &opr, expression_ptr branch0, expression_ptr branch1)
Definition: exprtk.hpp:9601
Definition: exprtk.hpp:4413
bfunc_t f0() const
Definition: exprtk.hpp:13896
Definition: exprtk.hpp:4414
bool joiner_enabled() const
Definition: exprtk.hpp:19427
std::size_t variable_count() const
Definition: exprtk.hpp:16777
static void print(const std::string &scalar_format, const vector_t &v)
Definition: exprtk.hpp:36491
function & expression(const std::string &e)
Definition: exprtk.hpp:35474
void skip_whitespace()
Definition: exprtk.hpp:2355
generic_type::string_view string_t
Definition: exprtk.hpp:36820
variable_ptr get_variable(const std::string &variable_name) const
Definition: exprtk.hpp:16811
Definition: exprtk.hpp:15201
static expression_node< T >::node_type type()
Definition: exprtk.hpp:12034
vector_node< T > * vec0_node_ptr_
Definition: exprtk.hpp:10318
static expression_node_ptr process(expression_generator< Type > &expr_gen, const details::operator_type &operation, expression_node_ptr(&branch)[2])
Definition: exprtk.hpp:32842
static void destroy(control_block *&cntrl_blck, SymTab *sym_tab)
Definition: exprtk.hpp:16680
vococov_t::type2 node_type
Definition: exprtk.hpp:32593
range_interface< T > irange_t
Definition: exprtk.hpp:14975
std::size_t size() const
Definition: exprtk.hpp:8952
assignment_rebasevec_elem_node(const operator_type &opr, expression_ptr branch0, expression_ptr branch1)
Definition: exprtk.hpp:9563
Definition: exprtk.hpp:4396
T pow_impl(const T v0, const T v1, real_type_tag)
Definition: exprtk.hpp:941
vds_t vds_
Definition: exprtk.hpp:9746
std::string str() const
Definition: exprtk.hpp:7598
void enable_zero_parameters(FunctionType &func)
Definition: exprtk.hpp:15794
exprtk::igeneric_function< T > igfun_t
Definition: exprtk.hpp:37927
ff13_functor f
Definition: exprtk.hpp:16169
any_true()
Definition: exprtk.hpp:37250
T value() const
Definition: exprtk.hpp:7154
parser< T > parser_t
Definition: exprtk.hpp:23133
T const_e_impl(real_type_tag)
Definition: exprtk.hpp:1316
Type type_t
Definition: exprtk.hpp:16209
cov_node< T, Operation > & operator=(const cov_node< T, Operation > &)
string_base_node< T > * str_base_ptr
Definition: exprtk.hpp:8263
const T & v0_
Definition: exprtk.hpp:13381
settings_store & enable_all_inequality_ops()
Definition: exprtk.hpp:19353
const T & ref() const
Definition: exprtk.hpp:6806
axpy< T > b1_axpy
Definition: exprtk.hpp:38181
static T process_5(const Sequence &arg_list)
Definition: exprtk.hpp:12628
const bool incrementor_deletable_
Definition: exprtk.hpp:6581
T value() const
Definition: exprtk.hpp:5598
T & RefType
Definition: exprtk.hpp:2002
bfunc_t f2() const
Definition: exprtk.hpp:13906
static T process(Type t1, Type t2, Type t3)
Definition: exprtk.hpp:11985
expression_node< typename node_type::value_type > * allocate_type(T1 t1, T2 t2, T3 t3) const
Definition: exprtk.hpp:15636
~return_envelope_node()
Definition: exprtk.hpp:11859
covovov_t::sf4_type sf4_type
Definition: exprtk.hpp:31861
token()
Definition: exprtk.hpp:2033
static expression_node_ptr process(expression_generator< Type > &expr_gen, const details::operator_type &operation, expression_node_ptr(&branch)[2])
Definition: exprtk.hpp:33237
operator_type operation() const
Definition: exprtk.hpp:15100
void begin()
Definition: exprtk.hpp:2242
details::vector_holder< T > vector_holder_t
Definition: exprtk.hpp:18236
Definition: exprtk.hpp:4270
void set_sf3m(sf3_map_t &sf3_map)
Definition: exprtk.hpp:25539
bool is_function(const std::string &function_name) const
Definition: exprtk.hpp:17367
std::string construct_subexpr(lexer::token &begin_token, lexer::token &end_token)
Definition: exprtk.hpp:20372
void load_operations_map(std::multimap< std::string, details::base_operation_t, details::ilesscompare > &m)
Definition: exprtk.hpp:15692
std::size_t local_var_stack_size
Definition: exprtk.hpp:35701
operator_type operation() const
Definition: exprtk.hpp:14938
opr_base< T >::Type Type
Definition: exprtk.hpp:12102
Definition: exprtk.hpp:16043
void set_ref(value_ptr *ref)
Definition: exprtk.hpp:5423
T pow_impl(const T v0, const T v1, int_type_tag)
Definition: exprtk.hpp:947
void update(const T &v0)
Definition: exprtk.hpp:35515
ifunction(const std::size_t &pc)
Definition: exprtk.hpp:15842
std::size_t size() const
Definition: exprtk.hpp:11663
bool branch_deletable_
Definition: exprtk.hpp:5701
value_t * end()
Definition: exprtk.hpp:4258
Definition: exprtk.hpp:2018
std::pair< std::string, symbol_type > symbol_t
Definition: exprtk.hpp:19070
Definition: exprtk.hpp:4437
bool parsing_return_stmt
Definition: exprtk.hpp:18988
Definition: exprtk.hpp:37828
settings_store & disable_all_control_structures()
Definition: exprtk.hpp:19374
type_store< igeneric_function< T >, igeneric_function< T > > string_function_store
Definition: exprtk.hpp:16610
type_view(const type_store_t &ts)
Definition: exprtk.hpp:4230
static const char * library
Definition: exprtk.hpp:38238
std::string synthesis_error_
Definition: exprtk.hpp:34670
T axnb(T a, T x, T b)
Definition: exprtk.hpp:8992
igeneric_function_t * igeneric_function_ptr
Definition: exprtk.hpp:11806
static T process_2(const Sequence &arg_list)
Definition: exprtk.hpp:12460
variable_node_ptr var0_
Definition: exprtk.hpp:7337
Definition: exprtk.hpp:4908
static details::operator_type operation()
Definition: exprtk.hpp:12066
expression_node< T >::node_type type() const
Definition: exprtk.hpp:5487
bool is_constant_string(const std::string &symbol_name) const
Definition: exprtk.hpp:18783
Definition: exprtk.hpp:18230
T operator()(const std::size_t &ps_index, parameter_list_t parameters)
Definition: exprtk.hpp:37167
symtab_list_t symbol_table_list_
Definition: exprtk.hpp:17916
string_literal_node< T > & operator=(const string_literal_node< T > &)
Definition: exprtk.hpp:14715
expression_node< T >::node_type type() const
Definition: exprtk.hpp:7970
Definition: exprtk.hpp:12120
static expression_node_ptr process(expression_generator< Type > &expr_gen, const details::operator_type &operation, expression_node_ptr(&branch)[2])
Definition: exprtk.hpp:29074
const T & v1_
Definition: exprtk.hpp:14388
igfun_t::parameter_list_t parameter_list_t
Definition: exprtk.hpp:38123
expression_node< T >::node_type type() const
Definition: exprtk.hpp:6023
std::deque< bool > brkcnt_list_
Definition: exprtk.hpp:34658
vocovov_t::sf4_type sf4_type
Definition: exprtk.hpp:32311
void register_local_var(expression_ptr expr)
Definition: exprtk.hpp:17833
T value() const
Definition: exprtk.hpp:15018
std::string str() const
Definition: exprtk.hpp:8688
bool is_return_node(const expression_node< T > *node)
Definition: exprtk.hpp:5117
static T process(const T &t0, const T &t1, const T &t2, const T &t3, const bfunc_t bf0, const bfunc_t bf1, const bfunc_t bf2)
Definition: exprtk.hpp:13594
Definition: exprtk.hpp:4454
void release()
Definition: exprtk.hpp:13429
bool enable_sequence_check_
Definition: exprtk.hpp:19793
T1 t1() const
Definition: exprtk.hpp:14079
conditional_string_node(expression_ptr test, expression_ptr consequent, expression_ptr alternative)
Definition: exprtk.hpp:8588
expression_node_ptr parse_define_var_statement()
Definition: exprtk.hpp:24160
T value() const
Definition: exprtk.hpp:8377
T sqrt_impl(const T v, real_type_tag)
Definition: exprtk.hpp:1301
value_t
the JSON type enumeration
Definition: json.h:407
std::size_t ref_count
Definition: exprtk.hpp:18301
igfun_t::generic_type generic_type
Definition: exprtk.hpp:37881
unsigned int batch_size
Definition: exprtk.hpp:4519
exprtk::igeneric_function< T > igfun_t
Definition: exprtk.hpp:37005
unary_op_map_t * unary_op_map_
Definition: exprtk.hpp:34363
bool type_check_enabled
Definition: exprtk.hpp:18992
static details::operator_type operation()
Definition: exprtk.hpp:12056
static T process(const std::string &t0, const std::string &t1, const std::string &t2)
Definition: exprtk.hpp:12208
range_pack< T > range_t
Definition: exprtk.hpp:7729
vec_data_store< T > vds_t
Definition: exprtk.hpp:10333
Definition: exprtk.hpp:13461
int to_int32_impl(const T v, real_type_tag)
Definition: exprtk.hpp:831
while_loop_bc_node(expression_ptr condition, expression_ptr loop_body)
Definition: exprtk.hpp:6363
static void assign(RefType t1, Type t2)
Definition: exprtk.hpp:12022
expression_node_ptr synthesize_string_expression(const details::operator_type &opr, expression_node_ptr(&branch)[2])
Definition: exprtk.hpp:33985
irange_ptr str0_range_ptr_
Definition: exprtk.hpp:7980
const T & v3_
Definition: exprtk.hpp:9320
expression_node< T > * expression_ptr
Definition: exprtk.hpp:14401
std::string str() const
Definition: exprtk.hpp:8808
details::expression_node< T > expression_node_t
Definition: exprtk.hpp:18129
Definition: exprtk.hpp:4449
data_pack()
Definition: exprtk.hpp:17579
const T1
Definition: exprtk.hpp:13628
virtual T operator()(parameter_list_t)
Definition: exprtk.hpp:11793
static expression_node_ptr process(expression_generator< Type > &expr_gen, const details::operator_type &operation, expression_node_ptr(&branch)[2])
Definition: exprtk.hpp:32673
T0 t0() const
Definition: exprtk.hpp:13876
expression_node_ptr parse_swap_statement()
Definition: exprtk.hpp:24429
boc_node(const expression_ptr brnch, const T const_var)
Definition: exprtk.hpp:14662
details::assignment_rebasevec_celem_node< T > assignment_rebasevec_celem_node_t
Definition: exprtk.hpp:18167
~rebasevector_elem_node()
Definition: exprtk.hpp:7146
value_type * value_ptr
Definition: exprtk.hpp:5248
range_t * range_ptr
Definition: exprtk.hpp:8743
static expression_node_ptr process(expression_generator< Type > &expr_gen, const details::operator_type &operation, expression_node_ptr(&branch)[2])
Definition: exprtk.hpp:33404
std::size_t get_variable_list(Sequence< std::string, Allocator > &vlist) const
Definition: exprtk.hpp:17269
Definition: exprtk.hpp:4453
void post()
Definition: exprtk.hpp:35613
igfun_t::parameter_list_t parameter_list_t
Definition: exprtk.hpp:37527
void clear()
Definition: exprtk.hpp:6838
string_base_node< T > * str_base_ptr
Definition: exprtk.hpp:8076
const char_t & front(const std::string &s)
Definition: exprtk.hpp:251
Definition: exprtk.hpp:4398
std::vector< expression_ptr > arg_list_
Definition: exprtk.hpp:6759
expression_node< T > * expression_ptr
Definition: exprtk.hpp:9293
const type_store & operator[](const std::size_t &index) const
Definition: exprtk.hpp:4187
igfun_t::parameter_list_t parameter_list_t
Definition: exprtk.hpp:37431
generic_type::vector_view vector_t
Definition: exprtk.hpp:37338
static T process_3(const Sequence &arg_list)
Definition: exprtk.hpp:12767
T root_impl(const T v0, const T v1, real_type_tag)
Definition: exprtk.hpp:992
static T evaluate(const Type x, const Type c8, const Type c7, const Type c6, const Type c5, const Type c4, const Type c3, const Type c2, const Type c1, const Type c0)
Definition: exprtk.hpp:35211
expression_node< T >::node_type type() const
Definition: exprtk.hpp:9873
T hypot(const T v0, const T v1)
Definition: exprtk.hpp:1454
std::string str() const
Definition: exprtk.hpp:8401
Definition: exprtk.hpp:16160
T xnor_opr(const T v0, const T v1)
Definition: exprtk.hpp:1517
static details::operator_type operation()
Definition: exprtk.hpp:12161
igfun_t::parameter_list_t parameter_list_t
Definition: exprtk.hpp:37880
char_cptr base() const
Definition: exprtk.hpp:7681
static expression_node< T > * allocate(Allocator &allocator, T0 p0, T1 p1, T2 p2, T3 p3, bfunc_t p4, bfunc_t p5, bfunc_t p6)
Definition: exprtk.hpp:13922
static T_ execute(ifunction &f, T_(&v)[15])
Definition: exprtk.hpp:11197
vector_holder< T > * vector_holder_ptr
Definition: exprtk.hpp:10826
details::for_loop_node< T > for_loop_node_t
Definition: exprtk.hpp:18139
bool register_scanner(lexer::token_scanner *scanner)
Definition: exprtk.hpp:3793
std::vector< symbol_table_t * > auxiliary_symtab_list_
Definition: exprtk.hpp:36130
igfun_t::parameter_list_t parameter_list_t
Definition: exprtk.hpp:37336
bool add_vector(const std::string &vector_name, T(&v)[N])
Definition: exprtk.hpp:17128
#define exprtk_disable_fallthrough_end
Definition: exprtk.hpp:81
axpyz< T > b1_axpyz
Definition: exprtk.hpp:38183
std::vector< data_ptr_t * > data_ref_
Definition: exprtk.hpp:4124
expression_node< T >::node_type type() const
Definition: exprtk.hpp:15150
static std::string id()
Definition: exprtk.hpp:13561
static bool is_null(const expression< T > &expr)
Definition: exprtk.hpp:17953
Definition: exprtk.hpp:16599
Definition: exprtk.hpp:19261
std::size_t size() const
Definition: exprtk.hpp:5623
bool is_valid(const expression< T > &expr)
Definition: exprtk.hpp:17960
std::deque< ptr_t > & deq_
Definition: exprtk.hpp:20773
range_t & range_ref()
Definition: exprtk.hpp:8957
vector_node_ptr vec() const
Definition: exprtk.hpp:9863
expression_node< T >::node_type type() const
Definition: exprtk.hpp:8713
virtual const T c() const =0
expression_node< T >::node_type type() const
Definition: exprtk.hpp:9723
Definition: exprtk.hpp:6973
Definition: exprtk.hpp:18104
bool is_integer_impl(const T &, int_type_tag)
Definition: exprtk.hpp:1355
T nequal(const T v0, const T v1)
Definition: exprtk.hpp:1412
func_4param()
Definition: exprtk.hpp:35783
Definition: exprtk.hpp:4424
Definition: exprtk.hpp:8312
expression_node< typename node_type::value_type > * allocate_rc(T1 &t1, const T2 &t2) const
Definition: exprtk.hpp:15489
T atan2(const T v0, const T v1)
Definition: exprtk.hpp:1461
expression_ptr alternative_
Definition: exprtk.hpp:6032
details::repeat_until_loop_bc_node< T > repeat_until_loop_bc_node_t
Definition: exprtk.hpp:18142
static std::string id(expression_generator< Type > &expr_gen, const details::operator_type o0, const details::operator_type o1, const details::operator_type o2)
Definition: exprtk.hpp:32469
std::string get_stringvar_name(const expression_ptr &ptr) const
Definition: exprtk.hpp:17402
const tfunc_t f_
Definition: exprtk.hpp:14024
range_pack< T > range_t
Definition: exprtk.hpp:8077
expression_node< T >::node_type type() const
Definition: exprtk.hpp:5677
bool cov_optimisable(const details::operator_type &operation, expression_node_ptr(&branch)[2]) const
Definition: exprtk.hpp:25859
igfun_t::generic_type generic_type
Definition: exprtk.hpp:37480
details::T0oT1oT2< T, T0, T1, T2, typename T0oT1oT2process< T >::mode1 > type1
Definition: exprtk.hpp:14330
token_t store_current_token_
Definition: exprtk.hpp:4059
details::assignment_string_node< T > assignment_string_node_t
Definition: exprtk.hpp:18159
std::string to_str(error_mode mode)
Definition: exprtk.hpp:18022
Definition: exprtk.hpp:37147
virtual T value(expression_t &e)
Definition: exprtk.hpp:35693
expression_node< T >::node_type type() const
Definition: exprtk.hpp:7169
vector_node_ptr vec() const
Definition: exprtk.hpp:9713
Definition: exprtk.hpp:4909
variable_ptr get_variable(const T &var_ref) const
Definition: exprtk.hpp:18620
bool symbol_exists(const std::string &symbol) const
Definition: exprtk.hpp:18802
const bool initialiser_deletable_
Definition: exprtk.hpp:6349
dot< T > dt
Definition: exprtk.hpp:38186
static const expression_node< T >::node_type result
Definition: exprtk.hpp:13661
vector_interface< T > * ivec_ptr_
Definition: exprtk.hpp:9475
std::size_t error_count() const
Definition: exprtk.hpp:3529
vector_node_ptr vec0_node_ptr_
Definition: exprtk.hpp:10657
igfun_t::parameter_list_t parameter_list_t
Definition: exprtk.hpp:37381
bool is_invalid_inequality_operation(const details::operator_type operation)
Definition: exprtk.hpp:20273
bool is_function(const expression_node< T > *node)
Definition: exprtk.hpp:5111
symbol_table_t::vararg_function_ptr vararg_function_ptr
Definition: exprtk.hpp:18556
bool initialised_
Definition: exprtk.hpp:8065
Definition: exprtk.hpp:4395
T1 t1_
Definition: exprtk.hpp:13752
func_3param()
Definition: exprtk.hpp:35769
static T process_2(const Sequence &arg_list)
Definition: exprtk.hpp:12598
generator_t lexer_
Definition: exprtk.hpp:4057
bool add_stringvar(const std::string &stringvar_name, std::string &s, const bool is_constant=false)
Definition: exprtk.hpp:17002
details::unary_node< T > unary_node_t
Definition: exprtk.hpp:18131
T value() const
Definition: exprtk.hpp:6015
void disable_has_side_effects(FunctionType &func)
Definition: exprtk.hpp:15817
T notl_impl(const T v, real_type_tag)
Definition: exprtk.hpp:1311
T value() const
Definition: exprtk.hpp:11700
Definition: exprtk.hpp:15754
Definition: exprtk.hpp:4398
expression_node< T >::node_type type() const
Definition: exprtk.hpp:11336
usr_symbol_type
Definition: exprtk.hpp:19001
assignment_string_node(const operator_type &opr, expression_ptr branch0, expression_ptr branch1)
Definition: exprtk.hpp:8339
getline()
Definition: exprtk.hpp:37013
const vds_t & vds() const
Definition: exprtk.hpp:10805
bool vardef_disabled() const
Definition: exprtk.hpp:19435
write()
Definition: exprtk.hpp:36900
generic_type::parameter_list parameter_list_t
Definition: exprtk.hpp:15960
expression_node_ptr synthesize_csros_expression(const details::operator_type &opr, expression_node_ptr(&branch)[2])
Definition: exprtk.hpp:33911
bool zero_return_disabled() const
Definition: exprtk.hpp:19437
expression_node< typename node_type::value_type > * allocate(const T1 &t1, const T2 &t2, const T3 &t3, const T4 &t4, const T5 &t5, const T6 &t6, const T7 &t7, const T8 &t8) const
Definition: exprtk.hpp:15597
~conditional_node()
Definition: exprtk.hpp:5997
Definition: exprtk.hpp:16137
vococov_t::type4 node_type
Definition: exprtk.hpp:33567
igfun_t::parameter_list_t parameter_list_t
Definition: exprtk.hpp:37006
vovovoc_t::type4 node_type
Definition: exprtk.hpp:33173
igfun_t::generic_type generic_type
Definition: exprtk.hpp:37106
Definition: exprtk.hpp:13210
details::conditional_node< T > conditional_node_t
Definition: exprtk.hpp:18135
expression< T > expression_t
Definition: exprtk.hpp:18174
vec_data_store< T > vds_t
Definition: exprtk.hpp:10517
Definition: exprtk.hpp:4438
retparam_list_t retparam_list_
Definition: exprtk.hpp:19217
expression_ptr loop_body_
Definition: exprtk.hpp:6263
Definition: exprtk.hpp:5705
covovov_t::type1 node_type
Definition: exprtk.hpp:31860
Definition: exprtk.hpp:20781
~vararg_node()
Definition: exprtk.hpp:9353
expression_node_ptr cardinal_pow_optimisation(const T &v, const T &c)
Definition: exprtk.hpp:28064
T0 t0_
Definition: exprtk.hpp:13936
igfun_t::generic_type generic_type
Definition: exprtk.hpp:37739
Definition: exprtk.hpp:4454
sumk()
Definition: exprtk.hpp:37796
range_t * range_ptr
Definition: exprtk.hpp:8584
expression_ptr branch_
Definition: exprtk.hpp:7839
static std::string id(expression_generator< Type > &expr_gen, const details::operator_type o0, const details::operator_type o1)
Definition: exprtk.hpp:30240
static T result(T v)
Definition: exprtk.hpp:1562
static std::string id(expression_generator< Type > &expr_gen, const details::operator_type o0, const details::operator_type o1, const details::operator_type o2)
Definition: exprtk.hpp:30656
std::size_t const_size() const
Definition: exprtk.hpp:6932
vec_data_store< T > vds_t
Definition: exprtk.hpp:7008
vocovoc_t::sf4_type sf4_type
Definition: exprtk.hpp:32948
bool is_invalid_string_op(const details::operator_type &operation, expression_node_ptr(&branch)[2])
Definition: exprtk.hpp:26020
expression_node< T >::node_type type() const
Definition: exprtk.hpp:10790
bool initialised_
Definition: exprtk.hpp:7476
Definition: exprtk.hpp:4420
std::size_t ref_count
Definition: exprtk.hpp:4613
Definition: exprtk.hpp:4432
bool is_string_node(const expression_node< T > *node)
Definition: exprtk.hpp:15316
vovovoc_t::sf4_type sf4_type
Definition: exprtk.hpp:30500
std::string type_id() const
Definition: exprtk.hpp:13816
#define token_inserter_empty_body
Definition: exprtk.hpp:3047
const bool branch_deletable_
Definition: exprtk.hpp:8308
T operator()(const std::size_t &ps_index, parameter_list_t parameters)
Definition: exprtk.hpp:37305
const value_ptr const_value_ptr
Definition: exprtk.hpp:5249
Definition: exprtk.hpp:2019
expression_node_ptr synthesize_veceqineqlogic_operation_expression(const details::operator_type &operation, expression_node_ptr(&branch)[2])
Definition: exprtk.hpp:27763
const type_store_t & operator[](const std::size_t &index) const
Definition: exprtk.hpp:4359
std::string str() const
Definition: exprtk.hpp:7518
vocovov_t::sf4_type sf4_type
Definition: exprtk.hpp:30668
bool is_boc_node(const expression_node< T > *node)
Definition: exprtk.hpp:15292
T value_type
Definition: exprtk.hpp:14138
static std::string id(expression_generator< Type > &expr_gen, const details::operator_type o0, const details::operator_type o1, const details::operator_type o2)
Definition: exprtk.hpp:31441
disabled_entity_set_t disabled_assignment_set_
Definition: exprtk.hpp:19807
const T c() const
Definition: exprtk.hpp:14425
Definition: exprtk.hpp:3553
build_string & operator<<(const std::string &s)
Definition: exprtk.hpp:390
Definition: exprtk.hpp:6039
std::vector< symbol_table< T > > symtab_list_t
Definition: exprtk.hpp:17563
const T & v1_
Definition: exprtk.hpp:9318
Definition: exprtk.hpp:4425
static T process_3(const Sequence &arg_list)
Definition: exprtk.hpp:12340
freefunc07(ff07_functor ff)
Definition: exprtk.hpp:16097
expression_node< T >::node_type type() const
Definition: exprtk.hpp:7296
Definition: exprtk.hpp:13509
T value() const
Definition: exprtk.hpp:8239
opr_base< T >::Type Type
Definition: exprtk.hpp:12041
bool cardinal_pow_optimisable(const details::operator_type &operation, const T &c)
Definition: exprtk.hpp:28085
expression_node< T > * expression_ptr
Definition: exprtk.hpp:9981
Definition: exprtk.hpp:16115
const T c() const
Definition: exprtk.hpp:14470
functor_t::bfunc_t bfunc_t
Definition: exprtk.hpp:13507
T atan2_impl(const T, const T, int_type_tag)
Definition: exprtk.hpp:1054
static bool compile_right_impl(expression_generator< Type > &expr_gen, const std::string &id, ExternalType t, expression_node_ptr &node, expression_node_ptr &result)
Definition: exprtk.hpp:29370
std::string ret_string_
Definition: exprtk.hpp:11681
bool is_left_bracket(const char_t c)
Definition: exprtk.hpp:132
T & ref()
Definition: exprtk.hpp:6801
void clear()
Definition: exprtk.hpp:3589
close< T > c
Definition: exprtk.hpp:37046
disabled_entity_set_t disabled_func_set_
Definition: exprtk.hpp:19803
std::string name
Definition: config.cpp:65
error_mode
Definition: exprtk.hpp:17967